Machine is defined based on the cookbook, ingredient set and available devices.
In Its turn the cookbook has a set of recipes where each recipe defines a list of required ingredients and the plan to cook the requested item from those ingredients.
In the simplest vending machine (the one dispensing sweets, water, juices, etc) each recipe defines just a single ingredient (countable ingredient) and a step (DispenseStep).
In a more complex case – the vending machine cooking coffee – the recipe can define if milk, coffee beans, or chocolate is required and in which proportion it should be mixed in. In this case
we need to define volume-based ingredients and the recipe will be multistep (PrepareGlassStep -> AddIngredientStep (coffee) -> AddIngredientStep (milk) -> AddSugarStep -> FinishCookingStep).
As it was mentioned above ingredients can be countable and volume-based.
The devices define capabilities of the vending machine, some devices are critical while others are less important. For example, the device that is cooking coffee is critical, while if one of the coin acceptor has failed it is not so critical if banknote acceptor or card reader are still working. Each device has a set of features. This way, to use a device the specific feature should be requested. This enables reusing the same device for several features.
In case of any failures the system should send alerts via alert manager. Alerts can have different importance level: INFO, WARNING, ERROR, CRITICAL, FATAL.
Privileged mode allows to maintain the vending machine, changing cash amount, adding or removing ingredients, changing the set of devices, etc. To switch to the privileged mode a special device should be polled to verify provided security token.
The hierarchy is mostly plain, composition is prioritized over inheritance. The main class is a Machine that serves as a facade class. For the user only the purchase flow is available, all other communications between devices are encapsulated in the device and device feature interfaces.
The extendable components are Step, Device, IngredientContainer.
Devices are created using the corresponding set up factories.
DeviceManager and Machine are observers for the device status.
Attributes: For each class, define the attributes (data) it will hold...
Methods: Define the methods (functions) that operate on the attributes. Ensure they align with the object's responsibilities and adhere to the principle of encapsulation.
public class Car { ... } // ExampleGood examples of single responsibility principle are
Open-closed principle
LSP
ISP
DIP
Easy to support new recipes or add additional steps. The list of devices is also very configurable.
Try creating a class, flow, state and/or sequence diagram using the diagramming tool. Mermaid flow diagrams can be used to represent system use cases. You can ask the interviewer bot to create a starter diagram if unfamiliar with the tool. Briefly explain your diagrams if necessary...
The state management can be quite hard given the large of set of external devices, so, it might make sense to invest into simplifying asynchronous communications or may be introduce a single state management flow.