I have a web application which has a shopping cart with cart items. The cart items are added to the user session, so must be serializable.
I have a checkout class which takes the cart items and saves them in the DB. There are some special types of cart items however which will require pre and post processing actions, for example, one of my cart items may be an event ticket, meaning that after purchase I must actually generate and save the ticket.
The question is, how do I add the logic of one module (ticket generation) to a completely unrelated module (shopping cart), while ensuring that the shopping cart is unaware of the existence of ticket generation, thus avoiding pollution of the domain.
For example:
interface ICartItem {
int quantity;
decimal amount;
string name;
// this interface has only checkout related
// data, no ticket related data
}
class Checkout {
void addCartItem(ICartItem cartItem) {
session.cartItems.Add(cartItem);
}
void doCheckout() {
foreach (var item in session.cartItems) {
saveCartItem(item);
// Now, somehow determine if the cart item is a
// ticket and if so save the ticket details
}
}
}
Note:
My backup plan is this:
interface ICartItem {
int quantity;
decimal amount;
string name;
// add ticket generation logic here and call it
// in the DoCheckout method
void onCheckoutComplete();
}
However, the organisation I am doing this for has a stack made of spaghetti, and it may be difficult to ensure that the ICartItem onCheckoutComplete() method will be called in all scenarios (present and future).
1 Answer 1
What if you inverted your logic? Instead of having a method saveCartItem(item)
, you instead call item.save()
and pass it the DB connection and any other resources it needs. Then the item can do whatever it needs to, and your checkout code doesn't have to worry about it.
-
+1 I like your answer, but most SE audience would tell you that persistence should be a different aspect and if cart items do the database updates it would be doing too much and would be hard coupled to a particular database engine that would change in the future, and that a complex persistence framework full of annotations like Hibernate should be used instead.Tulains Córdova– Tulains Córdova2016年02月24日 18:30:55 +00:00Commented Feb 24, 2016 at 18:30
-
This solution solves the problem in the same way as my fallback note. I will probably be implementing something similar, unless I can find a one stop solution which does everything I need and makes me breakfast at the same time.Shane– Shane2016年02月24日 18:58:52 +00:00Commented Feb 24, 2016 at 18:58
Explore related questions
See similar questions with these tags.
doCheckout()
will be called in all scenarios present and future?