jeudi 31 mai 2018

Cost calculator for Shopping Cart

Problem Statement: Design a system which helps calculate the TotalCost of the items in the Cart. You will be given a list of items in the Cart with Discounts like in the example below. The list would contain either items or discounts and the sequence matters:

Sample cart: $10 Book xyz, 10% Discount on all items, $20 stationary, 20% discount on next item, $100 Shirt, $15 off on 5th Item of Type Book.

Types of Discounts: 10% Discount on all items 20% discount on next item $15 off on 5th Item of Type Book (More type of Discounts can be added later to the system)

Here is my solution for this, I will appreciate pointers to improve further:

CartItem

package cart;

public interface CartItem {
    double value();
    String description();
}

**Coupon**
package cart;

public class Coupon implements CartItem {

    private double value;
    private String description;
    private String type;


    public Coupon(double value, String description, String type) {
        this.value = value;
        this.description = description;
        this.type = type;
    }

    public String getType() {
        return type;
    }

    @Override
    public double value() {
        return value;
    }

    @Override
    public String description() {
        return description;
    }
}


**Product**
package cart;

public class Product implements CartItem {

    private double unitPrice;
    private String name;

    public Product(double unitPrice, String name) {
        this.unitPrice = unitPrice;
        this.name = name;
    }

    @Override
    public double value() {
        return unitPrice;
    }

    @Override
    public String description() {
        return name;
    }
}

**Cart**

package cart;

import discount.Discount;
import discount.DollarDiscount;
import discount.PercentDiscount;

import java.util.*;

public class Cart {

    List<CartItem> cartItemList;

    public Cart() {
        cartItemList = new ArrayList<>();
    }

    public void add(CartItem cartItem) {
        cartItemList.add(cartItem);
    }

    private Discount getDiscountStrategy(Coupon coupon, Product product) {
        if(coupon.getType() == "PercentDiscountForAll" || coupon.getType() == "PercentDiscountForNext") {
            return new PercentDiscount(product, coupon);
        } else {
            return new DollarDiscount(product, coupon);
        }
    }

    private double checkout() {
        Map<Product, Integer> productMap = new LinkedHashMap<>();
        double total = 0;

        Iterator<CartItem> itemIterator = cartItemList.listIterator();

        while(itemIterator.hasNext()) {
            CartItem cartItem = itemIterator.next();
            if(cartItem instanceof Product) {
                productMap.put((Product) cartItem, productMap.getOrDefault(cartItem, 0)+1);
                total += cartItem.value();
            } else if (cartItem instanceof Coupon) {
                if(((Coupon) cartItem).getType() == "PercentDiscountForAll") {
                    for(Product product : productMap.keySet()) {
                        total = total - product.value();
                        double discountedPrice = getDiscountStrategy((Coupon) cartItem, product).applyDiscount();
                        total = total+discountedPrice;
                    }
                } else  if (((Coupon) cartItem).getType() == "PercentDiscountForNext") {
                    //Code and percent discount for next will come here.
                } else if (((Coupon) cartItem).getType() == "DollarDiscountForNth") {
                    //Code and dollar discount for Nth will come here.
                }
            }
        }
        return total;
    }

    public static void main(String[] args) {
        Cart cart = new Cart();
        CartItem apple1 = new Product(1, "Apple");
        CartItem apple2 = new Product(1, "Apple");
        CartItem apple3 = new Product(1, "Apple");
        CartItem coupon = new Coupon(10, "10% Percen Discount For All", "PercentDiscountForAll");
        cart.add(apple1);
        cart.add(apple2);
        cart.add(apple3);
        cart.add(coupon);
        System.out.println(cart.checkout());
    }

}

***Discount***
package discount;

public interface Discount {
    double applyDiscount();
}


**PercentDiscount**
package discount;

import cart.Coupon;
import cart.Product;

public class PercentDiscount implements Discount {

    private Product product;
    private Coupon coupon;

    public PercentDiscount(Product product, Coupon coupon) {
        this.product = product;
        this.coupon = coupon;
    }

    @Override
    public double applyDiscount() {
        double discountedPrice = product.value() - ((product.value() * 
                                 coupon.value())/100);
        return discountedPrice;
    }
}


**DollarDiscount**
package discount;

import cart.Coupon;
import cart.Product;

    public class DollarDiscount implements Discount {

        private Product product;
        private Coupon coupon;

        public DollarDiscount(Product product, Coupon coupon) {
            this.product = product;
            this.coupon = coupon;
        }

        @Override
        public double applyDiscount() {
            return product.value() - coupon.value();
        }
    }

I have tried to do this using both composite and strategy pattern, for discount I am trying to use Strategy Pattern and for items in cart I am trying to use Composite Pattern . I will highly appreciate any pointers to improve or simplify this.

Aucun commentaire:

Enregistrer un commentaire