2

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).

4
  • 2
    And the question is...?
    – Robbie Dee
    Feb 24, 2016 at 16:52
  • The question was in comments in the doCheckout() method of the code example. I have made it more explicit now.
    – Shane
    Feb 24, 2016 at 17:08
  • "it may be difficult to ensure that the ICartItem onCheckoutComplete() method will be called in all scenarios (present and future)." Then how are you so sure doCheckout() will be called in all scenarios present and future? Feb 24, 2016 at 18:24
  • I am not sure! That is the problem. If I knew that doCheckout would be called, and doCheckout calls my onCheckout complete method then the problem would be solved :( .
    – Shane
    Feb 24, 2016 at 19:00

1 Answer 1

2

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.

2
  • +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. 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
    Feb 24, 2016 at 18:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.