Java Object Oriented Analysis and Design Problem
Added: (Sat Jan 27 2018)
Pressbox (Press Release) -
This is the second part of Java tutorial to show how to create Vending Machine in Java. In the first part, we have discussed problem statement and the solution itself, but unit testing and design document was still pending, which we'll see in this article.
As I said, there are multiple ways to implement Vending machine in Java e.g. you could have easily used state design pattern to implement a vending machine, in fact, it's one of the best examples of State design pattern. Vending machine behaves differently on different states e.g. return a product if the machine is not empty, otherwise, it just returns coins, so it ideally fits in state design pattern. Though, In our solution, I have not used the state design pattern but have just coded the solution with an if else block. This is easier because of a limited number of state and not many state transition but in more real world scenario, state design pattern is better as it uses Polymorphism and removes the logic we have put inside the if-else block.
Here is a sample design document for Vending Machine problem. Well, it's not that great but conveys my design decisions in text format. Since in a real test, time is critical you need to balance your time between coding, testing, and designing activity, it's better to choose text over an image. If you are good with UML than adding a class diagram would certainly help here.
In Short Design Document in Java Should include
- description of the solution
- design decision and data structures
- All classes and there responsibility
- description of the package
- description of methods
- the motivation of decision e.g. why this design pattern, why enum, why BigDecimal etc?
- Flow Chart of couple of use cases
- UML Diagram
Here is our sample design document, it's very basic because I have generated it very quickly, but it's good for learning and doing Object Oriented Analysis and design. One thing which I would like to add on this document is UML class diagram because that's another way to convey your design to fellow Java developers.
1) High-level Design
Includes overview of the problem, not necessary if you are writing this as part of the test because evaluator should be familiar with problem specification. Important if your design document is intended for someone who is not very familiar with the problem domain.
- Main interface, classes and Exceptions
- VendingMachine - an interface which defines public API of VendingMachine
- VendingMachineImpl - a general purpose implementation of VendingMachine interface
- Inventory - A type-safe inventory for holding objects, which is an ADAPTER or WRAPPER over java.util.Map
- Item - type-safe Enum to represent items supported by vending machine.
- Coin - type-safe Enum to represent coins, which is acceptable by vending machine.
- Bucket - A Holder class for holding two types together.
- SoldOutException - thrown when user selects a product which is sold out
- NotSufficientChangeException - thrown when Vending machine doesn't have enough change to support the current transaction.
- NotFullPaidException - thrown when the user tries to collect an item, without paying the full amount.
- Data structures used
- Map data structure is used to implement cash and item inventories.
- The List is used to returning changes because it can contain duplicates, i.e. multiple coins of the same denomination.
- Motivation behind design decisions
- Factory design pattern is used to encapsulate creation logic of VendingMachine.
- Adapter pattern is used to create Inventory by wrapping java.util.Map
- java.lang.Enum is used to represent Item and Coins, because of following benefits
- compile time safety against entering an invalid item and invalid coin.
- no need to write code for checking if selected item or entered coin is valid.
- reusable and well encapsulated.
- long is used to represent price and totalSales, which are the amount because we are dealing in cents.
Not used BigDecimal to represent money, because the vending machine can only hold limited amount, due to finite capacity of coin inventory.
2) Low Leven Design
- The getChange() method uses a greedy algorithm to find out whether we have sufficient coins to support an amount.
- When Vending Machine will be created, it's initialized with default cash and item inventory. current with quantity 5 for each coin and item.
2) Testing Strategy
- Three primary test cases to testWithExactPrice(), testWithMorePrice() and testRefund() to cover general usecase.
- Negative test cases like testing SoldOutException, NotSufficientChangeException or NotFullPaidException
- The design uses Abstraction to create reusable, small classes which are easier to read and test.
- Encapsulating Items and Coins on their respective class makes it easy to add new Coins and Items.
- Inventory is general purpose class and can be used elsewhere, It also encapsulates all inventory operations.
- Vending Machine is single-threaded, only one user will operate at a time.
- A call to reset() will reset item and balance i.e. make them zero.