Shopping Cart sample design considerations
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
- Changes:
- 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.
Comments
I don't think that I would automatically convert all the separate Harry Potter issues into a bundle, instead I would present the option to do so and explain the motivation (discount). Maybe the user made a mistake and didn't intend to order all of them but only all minus 1 (don't know how many books there are ;) if you would do the convention automatically then that means the customer notices his mistake and needs to manually add all individual books again minus the one he already had. That will be frustrating I believe.
So I believe suggesting something lie this is of high customer value, doing it automatically is not, because I cannot decide this for my customers.
-Mark
I'm curious to see where this series of posts ends up.
It would be nice to have a rules based system recommend purchases to customers and store the information to modify the cart with those recommendations. That way you could say something like when the total amount of Harry Potter books exceeds the price of the bundle, recommend the bundle instead. Then the presentation/controllers could modify the cart without actually going back to the product catalog. You would need a final inventory inquiry during check out to provide shipping estimates, but that's fine too.
You could also do it outside of the normal order flow and provide updated recommendations alongside the usual browsing experience asynchronously -- eliminating some latency in the end-user page load.
So keep it coming!
Chris,
This in particular is the example that I am using in the last chapter of my book.
The like the add only / audit trail aspect of what you suggest here. I have been considering it for the next major version of dashCommerce. The ShoppingCartView doesn't really "feel" right to me, but I'll be doing a lot of work in the near future and I'll play with the idea to see if it feels better after working with it.
Tracking quantity changes instead of quantity is an interesting idea, especially if you think in terms of tracking how a user shops (for instance if a message of 'buy 2 get 1 free' results in an increased sale).
I also think it isn't a good idea to automatically change items of a shopping cart. My way to shop is like browsing in firefox. Go thru the categories and put all what is interesting into the shopping cart. If i am ready to buy, i got to the shopping cart and think about what i really need and may remove something.
Comment preview