diagram { /* line-style: sloppy 0.3; */ } controlflow { dash-style: 0; } Model Name Here 1. Use Cases 2. Domain Analysis 3. Architectural Design 4. Detailed Design Use Cases Analyze functional requirements by identifying user roles – actors – and associating them to their use cases. (1.0, 0.0, 0.0, 1.0, 93.76953125, 79.1953125) (0.0, 0.0) 258.0 110.0 Use Case Scenarios Model abstract use case implementation by creating activity diagrams visualizing activity flows for primary and secondary use case scenarios. (1.0, 0.0, 0.0, 1.0, 58.0, 79.0) (0.0, 0.0) 364.0 95.0 Domain Entities Perform domain analysis by modeling domain entities and their relationships using simplified class diagram. This diagram will serve as a visual dictionary of concepts. It will also be a starting point for your design-level data model. (1.0, 0.0, 0.0, 1.0, 46.015625, 81.69921875) (0.0, 0.0) 400.0 100.0 Package Dependencies Interactions Interaction Prepare package dependencies diagram to group your implementation classes in appropriate way. This will help you maintain the code well structured and avoid design flaws such as cyclic dependencies or dependencies on unstable parts (1.0, 0.0, 0.0, 1.0, 106.71484375, 51.49999999999997) (0.0, 0.0) 271.5703125 144.0 Model component interactions for use case scenarios in order to find out new methods in existing classes or even new classes with specific responsibilities. (1.0, 0.0, 0.0, 1.0, 43.0, 73.0) (0.0, 0.0) 322.0 93.0 Detailed Class Design Create detailed class diagrams to capture your object-oriented data model. (1.0, 0.0, 0.0, 1.0, 126.22541649148083, -111.56346769146282) (0.0, 0.0) 215.0 76.0 Implementation Architecture Define the major artifacts that manifest implementation of your components. Indicate how they are deployed on hardware nodes, their inter-dependencies and communication protocols. (1.0, 0.0, 0.0, 1.0, -7.59375, 75.08984375) (0.0, 0.0) 271.0 129.0 Recommender (1.0, 0.0, 0.0, 1.0, 59.49042039678521, 676.7889605442139) (-4.473890692342593, 0.0) 581.5334231350598 103.7992092219963 recommend + Recommender(history_file: string, cache_db_file: Optional(string) = None) in count int 1 History (1.0, 0.0, 0.0, 1.0, 186.63282775878895, 443.60939025878906) (0.0, 0.0) 318.3008270263672 164.75778198242188 0 1 History in filename string 0 0 (1.0, 0.0, 0.0, 1.0, 427.1573380812623, 679.4648742675781) [(0.37800127420644003, -2.6759137233642605), (0.37800127420644003, -71.09770202636719)] 1 1 composite * * YouTubeHistory (1.0, 0.0, 0.0, 1.0, 86.18801116943362, 224.98699188232428) (0.0, 44.798164367675795) 181.64712270100912 58.35613250732423 0 0 FreeTubeHistory (1.0, 0.0, 0.0, 1.0, 380.05679575602204, 226.81316375732425) (0.0, 43.58071645100908) 249.7537180582683 57.138684590657604 0 0 0 0 (1.0, 0.0, 0.0, 1.0, 223.12159220377606, 442.6041793823242) [(0.0, 0.0), (0.6699211932502465, -114.46289062499994)] 0 0 (1.0, 0.0, 0.0, 1.0, 438.54807535807294, 442.6823043823242) [(0.0, 0.0), (0.3684514898106386, -115.14973958333326)] 1 + parse_history(filename: string) -> History When parse_history() is called, it should identify and return the correct history type. It can leverage the is_this_type() function that the implementers of this interface should have to identify whether it's the correct type. (1.0, 0.0, 0.0, 1.0, 531.3502782185875, 411.48828125) (0.0, 0.0) 170.39703369140614 229.0 1 + is_this_type(in filename: string) -> bool 1 + get_video(in index: int) -> Video 1 __iter__ 1 __size__ Video (1.0, 0.0, 0.0, 1.0, 863.6850618434581, 361.7811660068871) (0.0, 0.0) 644.0 161.64602675087428 0 0 + getID() -> string 0 + getWatchTime() -> float 0 + getWatchProgress() -> float 0 + getTitle() -> string 0 + getDescription() -> string Video in id string in watch_time float in watch_progress float in title string in description string