While it is highly likely that you have created a shopping cart in the past, this shopping cart design is slightly different. One thing that should be obvious is that this is still a simplified example, and in the real world you are likely to need to do more, but it is a good example of an important concept. In the image, you can see that we have the fairly standard Shopping Cart, Product and Item classes, where item represent the quantity of a particular product in the shopping cart.
But why do we need such things as Discounts, or why do we have a ChangeItemQuantity class? And most shopping carts don't have the concept of messages. This shopping cart is build in this manner in order to make sure that we can easily integrate a versatile back end into this, without creating cascading changes throughout the system.
It is also a good way to structure things in general, because we have an object model to which we are mostly only adding things, and only rarely modifying. This is important because using the addition only approach, we have a domain model that is auditable, and more flexible in the long term.
It also means that we can walk into any shopping cart, and ask it to explain what caused it to reached that particular total. Another important design consideration is the difference between an item in the cart (this is something that the user has explicitly added) and a change to the quantity of items in the cart (something that the back end did for the user).
As usual, I find that an example tends to make everything clearer. We have the following requirement: if you buy all seven of Harry Potter's books, you will actually pay for the Harry Potter bundle (for a reduced price).
Now, the user may select the bundle explicitly, or he may simply order each of the books, without being aware of the existence of that particular sale. In the domain model that we have in figure 13.1, we will model the second case as shopping cart with:
- Items - One item for each of the Harry Potter books
- One ChangeItemQuantity for each of the Harry Potter books, with AmountToChangeQuantity set to -1 (essentially removing all the books that the user has selected from the cart).
- One ChangeItemQuantity for the Harry Potter bundle, with AmountToChangeQuantity set to 1 (adding it to the cart).
- Messages - a message saying that you are now buying the Harry Potter bundle for a reduced price.
Note that in order to get that requirement working, we didn't have to modify the items that the user has selected. For presentation purposes, we also have a simplified view on top of a shopping cart, called, surprisingly enough, ShoppingCartView.The ShoppingCartView is very similar to a traditional Shopping Cart, it only have the concepts of items and messages. Items are what the user will end up buying (one bundle of Harry Potter books), and messages are information for the user. A discount, for example, is translated in the view into directly affecting the prices that you see on an item, as well as a message notifying the user that he got a particular discount.