--- title: "Jam 06 - Exercise 2" tags: - 2 ๐Ÿ“ in writing - 3 ๐Ÿงช in testing - 4 ๐Ÿฅณ done - classes - uml - exceptions - enums --- <!-- markdownlint-disable line-length single-h1 no-inline-html --> <!-- markdownlint-configure-file { "ul-indent": { "indent": 4 }, "link-fragments": {"ignore_case": true} } --> {%hackmd dJZ5TulxSDKme-3fSY4Lbw %} # Exercise 2 - Advanced UML Design & Relationships ## Overview - Exercise 2 Building on our retail store system from Jam 05 and the `Money` enum we just created in Exercise 1, we'll now design the transaction component that will process customer purchases. This exercise focuses on advanced UML concepts and class relationships, helping you understand how different parts of a retail system work together. You'll learn to model interactions between classes, represent different types of relationships, and document your design decisions effectively. ## The Problem - Exercise 2 Our retail store's product catalog is working well, but customers need a way to purchase items! The store manager has requested a transaction system with the following requirements: 1. Process customer transactions 2. Track products in each transaction 3. Calculate subtotals, tax, and final totals 4. Track transaction states (in progress, payment pending, completed, voided) 5. Validate all operations for security This is a real-world scenario that many developers face - taking a set of business requirements and translating them into a technical design. In this exercise, we'll focus specifically on the Transaction component, and in later exercises, we'll integrate it with the Register component. :::info ๐Ÿ’ก **Note About Money Enum** In this exercise, we'll focus only on the Transaction component and its relationship with Products and TransactionState. The Money enum you created in Exercise 1 won't be directly connected to the Transaction in this exercise. We'll integrate Money with the Register component in Exercise 4. ::: ## Design Process When teams start to brainstorm object-oriented designs, they often work with *metaphors* that help them align their thought processes about the objects they are encapsulating to match the attributes and behaviors of the real-world objects. For example, a message passing system has used postal envelopes as their metaphor, with a To:, From: and the actual contents of the enclosed letter. File systems use filing cabinets with folders and files. In our case, we have the advantage that our metaphor is already a real-world system that most people understand - a transaction or receipt! This gives us a great starting point for our design. When approaching complex system design, follow these key principles: 1. **Start Simple** - Begin with the most basic, independent pieces: - `TransactionState` enum is a good starting point - it's self-contained! - A `Transaction` class comes next - it depends on `TransactionState` and `Product` - Look for objects that don't depend on others - Build a solid foundation before adding complexity - Remember: Good design starts with the basics 2. **Analyze Dependencies** - Map out how objects need each other - Understand what must exist first - Think about what must exist before something else can work - Remember: Dependencies drive design decisions 3. **Consider Impact** - Think about how changes ripple through the system - Plan for future modifications - Consider maintenance and extensibility - Test classes with fewer dependencies first - Remember: Today's decisions affect tomorrow's options :::warning ๐Ÿ” **Dependency Tips** - Always identify dependencies before starting implementation - Document dependencies clearly in your UML diagrams - Consider how changes to one class might affect others - Test classes with fewer dependencies first ::: ### Task 1: Create a UML Class Diagram - Transaction Design Requirements Design a transaction system by analyzing these requirements and identifying the key objects, behaviors and relationships: - The cashier starts each sale by creating a new `transaction` and scanning `items` one by one until all `items` are processed. - For each scanned `product`, the system looks up its price and adds it to the running total while keeping track of all `products` in the current `transaction`. - When all `products` are scanned, the system calculates the final total including tax. - Each `transaction` progresses through specific states (such as in progress, payment pending, completed, or voided). - State transitions follow logical rules (e.g., a completed transaction cannot go back to in-progress). - All operations must be validated based on the current transaction state, with methods providing feedback on success or failure. - Each `transaction` must include a timestamp to record when it was created. - The system must allow correction of scanning mistakes by removing `products` from the current `transaction`. - The system must calculate subtotal, tax, and final total for each transaction. - Methods should return boolean values to indicate success or failure of operations. Think carefully about what nouns might represent objects in your system, what verbs indicate behaviors those objects should have, and how the objects need to work together. Consider what attributes each object needs to track its state, and ensure your design properly enforces the state transition rules. For the TransactionState, consider: - What states are needed for the full lifecycle of a transaction? - Which transitions between states should be allowed or disallowed? - How will you represent these transition rules in your UML? For the Transaction class, consider: - What attributes are needed to track the transaction's state and data? - What methods are needed to manage products and calculate totals? - What relationships does Transaction have with other classes? - What method signatures will properly represent the required behaviors? ### Required Steps - Creating Your UML Design 1. **Identify Objects** - Look for nouns in the requirements - these often represent potential classes - Consider which nouns represent independent entities vs attributes of other entities - Not every noun needs to be a class! Some may be attributes or even irrelevant - Some nouns might be "part of" other nouns, making them good candidates for attributes - Document your choices and reasoning 2. **Define States and Behaviors** - Look for adjectives and descriptors that become attributes - Look for verbs and actions that become methods - Think about what state transitions are possible - Consider what data each object must maintain - Remember: Methods should make sense for their class - Ask yourself: "Would this action make sense in the real world?" 3. **Document Relationships** - Show how classes work together - Indicate multiplicity - Use proper relationship types - Consider temporary vs permanent relationships - Add explanatory notes - Think about how changes to one class might affect others 4. **Document Assumptions and Constraints** - Clearly state business rules that impact your design - Document any assumptions you've made about the system - Note any constraints that influenced design decisions - Explain why certain design choices were made - Include rationale for architectural decisions - Add notes about potential future extensions - Remember: Well-documented assumptions help others understand your design intent ### Creating Your Diagram There is a good, easy-to-read tutorial on UML class diagrams posted on Moodle in the "Resources" section. Please read through the PDF. ![Moodle-Resource](https://www.dropbox.com/scl/fi/mx2ggv2e1u2av8ar5hrdc/Moodle-Resource.png?rlkey=j9hh6fqoyoarep3s05mez0cgh&raw=1) You can also skim **CHAPTER 3** of the UML for Java Programmers book by Robert C. Martin (Uncle Bob) at [UML for Java Programmers](https://learning.oreilly.com/library/view/uml-for-javatm/0131428489/) at O'Reilly. Click "Sign In" and put in your Bucknell email address (do NOT use the Sign in with Google option). You should have access to the book immediately. 1. Set up draw.io: - Open draw.io - Open your `Jam05.drawio` file - In the Menu, click on `File` and then `Make a copy` - Name the new file `Jam06.drawio` and save it where your stored your Jam05 file - Open the tab where you made your ProductCatalog diagram Note: You will add onto your existing diagram, so do not delete any existing classes! 2. Add advanced UML Changes. - In draw.io, click More Shapes in the bottom left corner. - Check the box for UML 2.5 which is in the Software section and click Apply. - You should see a new section in the palette with all the UML 2.5 shapes. - This gives you access to a more advanced version of a class box. ![Advanced-Shapes](https://www.dropbox.com/scl/fi/gjdaefz1jl1swq9m22u1o/Advanced-Shapes.png?rlkey=oul1kxs6qg36c436231d72mj5&raw=1) 3. Create your design: - Add the Transaction class with appropriate attributes and methods - Add the TransactionState enum with possible states - Show the relationship between Transaction and Product - Show the relationship between Transaction and TransactionState - Include multiplicity indicators - Document assumptions Once you're happy with your UML diagram, it's time to export it as a PNG file: 1. Select File -> Export as -> PNG 2. In the export dialog: - In the "Include a copy of my digram" section, select "Current Page". This is to ensure you don't end up with the example diagram in your export. - Click Export 3. In the Save As dialog: - Save the file as `Jam06-uml.drawio.png` in your `jam06` folder - In the "Where" box, select "Download" - Click OK 4. The file will be in your downloads folder. Move it to your `src/main/java/jam06` folder. ## UML Diagram Requirements Your diagram should include: 1. Transaction class with attributes and methods 2. TransactionState enum with possible states 3. Relationship between Transaction and Product 4. Relationship between Transaction and TransactionState 5. Proper multiplicity indicators 6. Clear documentation of assumptions :::warning ๐Ÿšง **Common UML Pitfalls** Watch out for these common mistakes: 1. Missing multiplicity indicators 2. Incorrect relationship types 3. Forgetting to document assumptions 4. Omitting important methods ::: ## Verifying Your Design Before finalizing your diagram, check: 1. **Completeness** - All required classes present - All relationships shown - Proper multiplicity notation - Clear documentation 2. **Correctness** - Relationship types accurate - Method signatures complete - Visibility indicators present 3. **Clarity** - Diagram is readable - Relationships are clear - Notes explain complexity - Design intent is obvious > ๐Ÿ” **Checkpoint** > > Before proceeding, verify: > > - Your UML diagram includes all required classes (Transaction, TransactionState, Product) > - All relationships between classes are shown with proper arrows > - Multiplicity indicators are present on all relationships > - Class attributes and methods are clearly defined with visibility indicators > - State transitions are documented (either in the diagram or notes) > - Your diagram is exported as `Jam06-uml.drawio.png` in the correct location ## Save Your Work - Exercise 2 **Export your diagram**: Using the steps from the last jam, export the image and put it in your `jam06` folder. **Stage your changes**: ```bash git add src/main/java/jam06/Jam06-uml.drawio.png ``` **Verify what files are still uncommitted (no red files/folders)**: ```bash git status # Resolve any red files/folders ``` **Commit your work**: ```bash git commit -m "jam06: Complete UML design for transaction system" ``` **Your working directory should now be clean.** Remember: A good UML diagram is worth a thousand lines of code - take time to make it clear and complete!