I am building a WMS with the following basic requirements:
- Each Item can be in multiple Locations.
- A Location can contain multiple Items.
- For each Location / item combination, I must be able to track: QtyOnHand, QtyReserved, and QtyAvailable.
- One Location can contain another Location.
The basic required behaviour of a Location, is:
- Adding/Removing an Item with a Quantity.
- Adding/Removing a nested Location.
- Tracking Quantities for each Item within the Location.
I am attempting to write the code while staying faithful to OOP design principles, namely:
- Designing class interfaces to reflect behaviour rather than data.
- Avoiding Getter/Setters.
- Tell, don't Ask, as much as possible.
With that in mind, here is the basic code for a Location:
public class Location{ private final Map<InventoryItem, Integer> items = new HashMap<>(); private final Set<Location> locations = new HashSet<>(); public void add(InventoryItem item, int quantity) { if (items.containsKey(item)) { InventoryQuantity inventoryQuantity = items.get(item); items.put(item, inventoryQuantity.addQuantityOnHand(quantity)); } else { items.put(item, quantity); } } public void add(Location location) { locations.add(location); } public void remove(InventoryItem item, int quantity) { if (items.keySet().contains(item)) { if ((items.get(item) - quantity) == 0) { items.remove(item); } else { items.put(item, items.get(item) - quantity); } } } public void remove(Location location) { locators.remove(location); } } So I now that I have the basic behaviour for Adding/Removing, I am having difficulty figuring out what would be the best way to track quantity. I could create an InventoryQuantity class, as follows:
public class InventoryQuantity { private InventoryItem item; private int quantityOnHand; private int quantityReserved; private int quantityAvailable; public InventoryItem getItem() { return item; } public void setItem(InventoryItem item) { this.item = item; } public int getQuantityOnHand() { return quantityOnHand; } public void setQuantityOnHand(int quantityOnHand) { this.quantityOnHand = quantityOnHand; } public int getQuantityReserved() { return quantityReserved; } public void setQuantityReserved(int quantityReserved) { this.quantityReserved = quantityReserved; } public int getQuantityAvailable() { return quantityAvailable; } public void setQuantityAvailable(int quantityAvailable) { this.quantityAvailable = quantityAvailable; } } and store one InventoryQuantity for each InventoryItem in Location, like so:
private final Map<InventoryItem, InventoryQuantity> items = new HashMap<>(); My questions/issues are as follows:
- InventoryQuantity does not seem to be a real world object with a defined behavior; rather, it seems to be a data structure with the sole purpose of storing quantity data (as evidenced by the existance of Getter/Setters); is there a better way?
- Is asking a location to getQuantityOnHandForItem(item) a violation of Tell, don't Ask? On the other hand, there does not seem to be a better way of retreiving data...
I actually had some more questions, but this is what I remember at the moment. If anyone can help me understand/apply the principles effectively, I would greatly appreciate it!