The UML is listed below. There are different products with different preferential strategies. After adding these products into the shopping cart, the caller needs to call the checkout()
method to calculate the totalPrice
and loyaltyPoints
according to its specific preferential strategy. But when a new product comes with a new preferential strategy, I need to add another else if
. This currently breaks the open-closed principle.
class ShopppingCart {
// ...
public Order checkout() {
double totalPrice = 0;
Map<String,Integer> buy2Plus1=new HashMap<>();
int loyaltyPointsEarned = 0;
for (Product product : products) {
double discount = 0;
if (product.getProductCode().startsWith("DIS_10")) {
discount = (product.getPrice() * 0.1);
loyaltyPointsEarned += (product.getPrice() / 10);
} else if (product.getProductCode().startsWith("DIS_15")) {
discount = (product.getPrice() * 0.15);
loyaltyPointsEarned += (product.getPrice() / 15);
} else if(product.getProductCode().startsWith("DIS_20")){
discount=(product.getPrice()*0.2);
loyaltyPointsEarned+=(product.getPrice()/20);
}else if(product.getProductCode().startsWith("Buy2Plus1")){
if(buy2Plus1.containsKey(product.getProductCode())){
buy2Plus1.put(product.getProductCode(), buy2Plus1.get(product.getProductCode())+1);
}
else{
buy2Plus1.put(product.getProductCode(),1);
}
if(buy2Plus1.get(product.getProductCode())%3==0){
discount+=product.getPrice();
continue;
}
loyaltyPointsEarned+=(product.getPrice()/5);
}else {
loyaltyPointsEarned += (product.getPrice() / 5);
}
totalPrice += product.getPrice() - discount;
}
return new Order(totalPrice, loyaltyPointsEarned);
}
ShoppingCart
(something I deem insufficient) or can be extended toProduct
.