the beverage prices refactoring

Cette semaine, c'est Alice qui vous propose un #KataOfTheWeek : Le prix des boissons (beverage prices refactoring)

Briefing du Kata : Le code calcule le prix de différentes boissons qui sont vendues dans un café. Des suppléments peuvent être ajoutés à ces boissons. Chaque supplément fait augmenter le prix de la boisson.

Le but du kata est d'ajouter un supplément optionnel de cannelle à 0.05€ au catalogue de boissons existant. Il faut réfactorer le code avant d'ajouter la nouvelle feature.

Le code initial peut être trouvé ici : https://github.com/trikitrok/beveragespricingrefactoring_kata

Saurez-vous résoudre le problème ?

Bon courage !


Et voici une solution proposée par l'auteur en Java :

interface Beverage {
    double price();
}
class Coffee implements Beverage {
    @Override
    public double price() {
        return 1.2;
    }
}
class HotChocolate implements Beverage {
    @Override
    public double price() {
        return 1.45;
    }
}
class Tea implements Beverage {
     @Override
     public double price() {
         return 1.5;
     }
}
interface Topping {
    double price();
}
class Milk implements Topping {
    @Override
    public double price() {
        return 0.10;
    }
}
class Cream implements Topping{
    @Override
    public double price() {
        return 0.15;
    }
}
class Cinnamon implements Topping {
    @Override
    public double price() {
        return 0.05;
    }
}
class Drink {
    private Beverage beverage;
    private List<Topping> toppingList;

    public double price(){
        return beveragePrice() + toppingPrice();
    }

    private double beveragePrice(){
        if (this.beverage != null) {
            return this.beverage.price();
        }
        return 0;
    }

    private double toppingPrice(){
        return this.toppingList.stream()
            .filter(Objects::nonNull)
            .map(topping -> topping.price())
            .reduce(0d, (a, b) -> a + b);
    }
    public Drink(Beverage beverage){
        this(beverage, Collections.emptyList());
    }

    public Drink(Beverage beverage, List<Topping> toppingList){
        this.beverage = beverage;
        this.toppingList = toppingList == null ? Collections.emptyList() : toppingList;
    }
}

// tests part
class BeveragesPricingTest {
    @Test
    public void computes_no_beverage_price() {
        Drink coffee = new Drink(null);
        assertThat(coffee.price(), is(closeTo(0, 0.001)));
    }

    @Test
    public void computes_coffee_price() {
        Drink coffee = new Drink(new Coffee());
        assertThat(coffee.price(), is(closeTo(1.20, 0.001)));
    }

    @Test
    public void computes_tea_price() {
        Drink tea = new Drink(new Tea());
        assertThat(tea.price(), is(closeTo(1.50, 0.001)));
    }

    @Test
    public void computes_hot_chocolate_price() {
        Drink hotChocolate = new Drink(new HotChocolate());
        assertThat(hotChocolate.price(), is(closeTo(1.45, 0.001)));
    }

    @Test
    public void computes_tea_with_milk_price() {
        Drink teaWithMilk = new Drink(new Tea(), List.of(new Milk()));
        assertThat(teaWithMilk.price(), is(closeTo(1.60, 0.001)));
    }

    @Test
    public void computes_coffee_with_milk_price() {
        Drink coffeeWithMilk = new Drink(new Coffee(), List.of(new Milk()));
        assertThat(coffeeWithMilk.price(), is(closeTo(1.30, 0.001)));
    }

    @Test
    public void computes_coffee_with_milk_and_cream_price() {
        Drink coffeeWithMilkAndCream = new Drink(new Coffee(), List.of(new Milk(), new Cream()));
        assertThat(coffeeWithMilkAndCream.price(), is(closeTo(1.45, 0.001)));
    }

    @Test
    public void computes_hot_chocolate_with_cream_price() {
        Drink hotChocolateWithCream = new Drink(new HotChocolate(), List.of(new Cream()));
        assertThat(hotChocolateWithCream.price(),  is(closeTo(1.60, 0.001)));
    }

    @Test
    public void computes_hot_chocolate_with_cream_and_cinnamon_price() {
        Drink hotChocolateWithCreamCinnamon = new Drink(new HotChocolate(), List.of(new Cream(), new Cinnamon()));
        assertThat(hotChocolateWithCreamCinnamon.price(),  is(closeTo(1.65, 0.001)));
    }
}

Votre équipe TakiVeille

TakiVeille

TakiVeille