1

I am creating a web application in java where I need to mock the following flow.

When user trigger a certain process (add product to cart), I need to pass through following steps

  1. Need to see in HTTP Session if user is logged in.
  2. Check HTTP Session if shopping cart is there
  3. If user exist in HTTP Session and his/her cart do not exist in HTTP Session
  4. Get user cart from the database.
  5. add item to cart and save it to HTTP session and update cart in DB.
  6. If cart does not exist in DB, create new cart and and save in it HTTP Session.

Though I missed a lot of use cases here (do not want question length to increase a lot), but most of the flow will be same as I described in above steps.

My flow will start from the Controller and will go towards Service Layer and than ends up in the DAO layer.

Since there will be a lot of use cases where I need to check HTTP session and based on that need to call Service layer, I was planning to add a Facade layer which should be responsible to do this for me like checking Session and interacting with Service layer.

Please suggest if this is a valid approach or any other best approach can be implemented here?

One more point where I am confused is how to handle HTTP session in facade layer? do I need to pass HTTP session object each time I call my Facade or any other approach can be used here?

1
  • Just to handle few getAttribute() and setAttribute() of HttpSession , do you really need a Facade ? In case you eventually follow that approach , then pass the request around and not the HttpSession object .
    – AllTooSir
    Commented Apr 17, 2013 at 5:10

2 Answers 2

2

When I look at your use case, I start thinking about separation of concerns.

  • The controller shouldn't care if the cart is in the request or not.
  • The service call that adds Items to a cart shouldn't care if the user is logged in or not.

I then think:

  • Request objects are a pain in the butt to test with
  • A Facade feels kind of vague for specific use cases. What if we could create a simple Data Transfer Object for each use case that has the data needed?

So I would start with something like:

Controller

Status addItemToCart(HttpServletRequest request, Item item) {
  if(request.getSession(false) == null) return needLogin(request)

  UserCart cart = service.addItemToCart(item, new UserCart(session))
  return cart.saveToSession(session)
}

Service

UserCart addItemToCart(Item item, UserCart userCart) {
  if userCart.needsCart() {
     userCart = cartDAO.getNewCart(userCart)
  }
  userCart.addItem(Item)
  return cartDAO.updateCart(userCart)
}

My Service layer tests would insist on something like UserCart to keep me from having to mock HTTPServletRequests and create 10 lines of setup code. UserCart is just a dumb Data Transfer Object with some convenience methods, but it makes everything much simpler to understand. User has-a shopping cart is important to this use case, so it's where my brain goes pretty quickly. This also allows us to avoid all the null checks and nested blocks that become rampant when you go out of your way to avoid creating simple domain specific concepts.


1

I would always want to code my application in simplest of manner . I would have done all these in my Service layer itself. Below is my noob pseudo-code :

 /**
 * @param request HttpServletRequest
 * @param item Item to be added
 */
private void addItemToCart(HttpServletRequest request, Item item) {

    UserVO user = null;
    ShoppingCart cart = null;
    ShoppingCartDAO cartDAO = new ShoppingCartDAO();
    HttpSession session = request.getSession(false);
    // check if its an existing session
    if(session!=null){
        // get the user ifo from the session
        user = (UserVO)session.getAttribute("userVO");
        // try to get the cart from the session
        cart = (ShoppingCart)session.getAttribute("cart");

        if(cart==null) {
            // try to get the cart from DB
            cart = cartDAO.getShoppingCart(user);
            if(cart==null){
                // create a new cart
                ShoppingCart cart = new ShoppingCart(user);
            }
        }
        // add item to the  cart
        cart.addItem(item);
        // set it in session
        session.setAttribute("cart",cart);
        // update the DB
        cartDAO.updateShoppingCart(user);
    }

}

EDIT : I believe you can create an Interface to wrap the request object and pass the implementation of the Interface as argument to the Service method .

1
  • I am agree with you about simplicity, but is it ok to pass request object to service layer? Commented Apr 17, 2013 at 6:55

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.