Skip to content

Commit

Permalink
feat: implement delivery strategies
Browse files Browse the repository at this point in the history
  • Loading branch information
akadir committed Sep 13, 2020
1 parent 5f4cf12 commit 8b1a882
Show file tree
Hide file tree
Showing 9 changed files with 234 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.github.akadir.casestudy.delivery;

public interface Deliverable {
int getProductCount();

int getDeliveryCount();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.github.akadir.casestudy.delivery.strategy;

import io.github.akadir.casestudy.delivery.Deliverable;

public interface DeliveryStrategy {
double calculateDeliveryCost(Deliverable deliverable);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.github.akadir.casestudy.delivery.strategy;

import io.github.akadir.casestudy.delivery.Deliverable;

public class FedexDelivery implements DeliveryStrategy {
private final double costPerProduct;
private final double costPerDelivery;

public FedexDelivery(double costPerProduct, double costPerDelivery) {
this.costPerProduct = costPerProduct;
this.costPerDelivery = costPerDelivery;
}

@Override
public double calculateDeliveryCost(Deliverable deliverable) {
if (deliverable.getDeliveryCount() == 0) {
return 0;
} else {
return costPerDelivery * deliverable.getDeliveryCount() + costPerProduct * deliverable.getProductCount();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.github.akadir.casestudy.delivery.strategy;

import io.github.akadir.casestudy.delivery.Deliverable;

public class UPSDelivery implements DeliveryStrategy {
private final double costPerProduct;
private final double costPerDelivery;

public UPSDelivery(double costPerProduct, double costPerDelivery) {
this.costPerProduct = costPerProduct;
this.costPerDelivery = costPerDelivery;
}

@Override
public double calculateDeliveryCost(Deliverable deliverable) {
if (deliverable.getDeliveryCount() == 0) {
return 0;
} else {
return costPerDelivery + deliverable.getProductCount() * costPerProduct;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package io.github.akadir.casestudy.shopping.model;

import io.github.akadir.casestudy.delivery.Deliverable;
import io.github.akadir.casestudy.discount.campaign.base.Campaign;
import io.github.akadir.casestudy.discount.coupon.base.Coupon;
import io.github.akadir.casestudy.product.model.Product;

import java.util.HashMap;
import java.util.Map;

public class ShoppingCart {
public class ShoppingCart implements Deliverable {
private final Map<Product, Integer> products;
private Coupon appliedCoupon;
private Campaign appliedCampaign;
Expand Down Expand Up @@ -49,4 +50,12 @@ public double getCartPrice() {
return products.entrySet().stream()
.mapToDouble(e -> e.getKey().getPrice() * e.getValue()).sum();
}

public int getDeliveryCount() {
return products.size();
}

public int getProductCount() {
return products.values().stream().mapToInt(a -> a).sum();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.github.akadir.casestudy.discount.campaign.base.Campaign;
import io.github.akadir.casestudy.discount.coupon.base.Coupon;
import io.github.akadir.casestudy.product.model.Product;
import io.github.akadir.casestudy.shopping.model.ShoppingCart;

import java.util.Map;

Expand All @@ -24,5 +25,7 @@ public interface ShoppingCartService {

double getDiscounts();

ShoppingCart getShoppingCart();

Map<Product, Integer> getProducts();
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import io.github.akadir.casestudy.discount.campaign.base.Campaign;
import io.github.akadir.casestudy.discount.coupon.base.Coupon;
import io.github.akadir.casestudy.product.model.Product;
import io.github.akadir.casestudy.shopping.service.ShoppingCartService;
import io.github.akadir.casestudy.shopping.model.ShoppingCart;
import io.github.akadir.casestudy.shopping.service.ShoppingCartService;
import io.github.akadir.casestudy.shopping.validator.CartEventValidator;
import io.github.akadir.casestudy.shopping.validator.impl.AmountValidator;
import io.github.akadir.casestudy.shopping.validator.impl.ProductValidator;
Expand Down Expand Up @@ -173,6 +173,11 @@ public double getDiscounts() {
return shoppingCart.getDiscount();
}

@Override
public ShoppingCart getShoppingCart() {
return shoppingCart;
}

public Map<Product, Integer> getProducts() {
return Collections.unmodifiableMap(shoppingCart.getProducts());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package io.github.akadir.casestudy.delivery.strategy;

import io.github.akadir.casestudy.delivery.Deliverable;
import io.github.akadir.casestudy.delivery.strategy.DeliveryStrategy;
import io.github.akadir.casestudy.delivery.strategy.FedexDelivery;
import io.github.akadir.casestudy.product.model.Category;
import io.github.akadir.casestudy.product.model.Product;
import io.github.akadir.casestudy.shopping.service.ShoppingCartService;
import io.github.akadir.casestudy.shopping.service.impl.ConcreteShoppingCartServiceImpl;
import org.junit.Before;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;

public class FedexDeliveryTest {
private ShoppingCartService shoppingCartService;

@Before
public void init() {
shoppingCartService = new ConcreteShoppingCartServiceImpl();
}

@Test
public void whenUPSDeliveryCostCalculatedWithNonEmptyProductCartThenExpectCorrectCost() {
Category category = new Category("Accessories");
Product product = new Product("bag", 50, category);

shoppingCartService.addProduct(product);

double costPerDelivery = 3;
double costPerProduct = 1;

DeliveryStrategy deliveryStrategy = new FedexDelivery(costPerProduct, costPerDelivery);

Map<Product, Integer> productsBackup = new HashMap<>(shoppingCartService.getProducts());

Deliverable deliverable = shoppingCartService.getShoppingCart();

assertThat(deliveryStrategy.calculateDeliveryCost(deliverable))
.as("Delivery cost should be correct")
.isEqualTo(costPerDelivery + costPerProduct);

assertThat(shoppingCartService.getProducts())
.as("Shopping cart should not be modified in delivery cost calculation")
.isEqualTo(productsBackup);

Product anotherProduct = new Product("back bag", 100, category);

shoppingCartService.addProduct(anotherProduct, 2);

productsBackup = new HashMap<>(shoppingCartService.getProducts());

assertThat(deliveryStrategy.calculateDeliveryCost(deliverable))
.as("Delivery cost should be correct")
.isEqualTo((costPerDelivery * deliverable.getDeliveryCount()) + (costPerProduct * deliverable.getProductCount()));

assertThat(shoppingCartService.getProducts())
.as("Shopping cart should not be modified in delivery cost calculation")
.isEqualTo(productsBackup);
}

@Test
public void whenUPSDeliveryCostCalculatedWithEmptyCartThenExpectZeroCost() {
DeliveryStrategy deliveryStrategy = new FedexDelivery(1, 3);

Map<Product, Integer> productsBackup = new HashMap<>(shoppingCartService.getProducts());

assertThat(deliveryStrategy.calculateDeliveryCost(shoppingCartService.getShoppingCart()))
.as("Delivery cost should be zero for empty cart")
.isZero();

assertThat(shoppingCartService.getProducts())
.as("Shopping cart should not be modified in delivery cost calculation")
.isEqualTo(productsBackup);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package io.github.akadir.casestudy.delivery.strategy;

import io.github.akadir.casestudy.delivery.strategy.DeliveryStrategy;
import io.github.akadir.casestudy.delivery.strategy.UPSDelivery;
import io.github.akadir.casestudy.product.model.Category;
import io.github.akadir.casestudy.product.model.Product;
import io.github.akadir.casestudy.shopping.service.ShoppingCartService;
import io.github.akadir.casestudy.shopping.service.impl.ConcreteShoppingCartServiceImpl;
import org.junit.Before;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;

public class UPSDeliveryTest {

private ShoppingCartService shoppingCartService;

@Before
public void init() {
shoppingCartService = new ConcreteShoppingCartServiceImpl();
}

@Test
public void whenUPSDeliveryCostCalculatedWithNonEmptyProductCartThenExpectCorrectCost() {
Category category = new Category("Accessories");
Product product = new Product("bag", 50, category);

shoppingCartService.addProduct(product);

double costPerDelivery = 3;
double costPerProduct = 1;

DeliveryStrategy deliveryStrategy = new UPSDelivery(costPerProduct, costPerDelivery);

Map<Product, Integer> productsBackup = new HashMap<>(shoppingCartService.getProducts());

assertThat(deliveryStrategy.calculateDeliveryCost(shoppingCartService.getShoppingCart()))
.as("Delivery cost should be correct")
.isEqualTo(costPerDelivery + costPerProduct);

assertThat(shoppingCartService.getProducts())
.as("Shopping cart should not be modified in delivery cost calculation")
.isEqualTo(productsBackup);

Product anotherProduct = new Product("back bag", 100, category);

shoppingCartService.addProduct(anotherProduct, 2);

productsBackup = new HashMap<>(shoppingCartService.getProducts());

assertThat(deliveryStrategy.calculateDeliveryCost(shoppingCartService.getShoppingCart()))
.as("Delivery cost should be correct")
.isEqualTo(costPerDelivery + 3 * costPerProduct);

assertThat(shoppingCartService.getProducts())
.as("Shopping cart should not be modified in delivery cost calculation")
.isEqualTo(productsBackup);

}

@Test
public void whenUPSDeliveryCostCalculatedWithEmptyCartThenExpectZeroCost() {
DeliveryStrategy deliveryStrategy = new UPSDelivery(1, 3);

Map<Product, Integer> productsBackup = new HashMap<>(shoppingCartService.getProducts());

assertThat(deliveryStrategy.calculateDeliveryCost(shoppingCartService.getShoppingCart()))
.as("Delivery cost should be zero for empty cart")
.isZero();

assertThat(shoppingCartService.getProducts())
.as("Shopping cart should not be modified in delivery cost calculation")
.isEqualTo(productsBackup);
}
}

0 comments on commit 8b1a882

Please sign in to comment.