Home:ALL Converter>Replace conditional with polymorphism

Replace conditional with polymorphism

Ask Time:2018-01-22T16:39:25         Author:user1298426

Json Formatter

I am trying to understand this clean code practice with an example. Consider a class Product having switch case for discount. I am trying to replace switch statement with polymorphism.

Before code:

class Product {
    String priceCode;
    int discount;

    Product(String priceCode) {
        setDiscount(priceCode);
    }

    public int getDiscount() {
        return discount;
    }

    public void setDiscount(String priceCode) {
        switch (priceCode) {
            case "CODE1":
                discount = // some logic;
            case "CODE2":
                discount = // some other logic;
            case "CODE3":
                discount = // some other logic;
        }
    }
}

In below code as you can see I removed switch statement but I still have if conditions to create an object of discountStrategy. My question is I still have if conditions which I am trying to remove with Polymorphism.

After code:

class Product {
    String priceCode;
    DiscountStrategy discountStrategy;

    Product(String priceCode) {
        setDiscount(priceCode);
    }

    public int getDiscount() {
        return discountStrategy.getDiscount();
    }

    public void setDiscount(String priceCode) {
        if (priceCode.equals("CODE1")) {
            discountStrategy = new DiscountStrategy1();
        } else if (priceCode.equals("CODE2")) {
            discountStrategy = new DiscountStrategy2();
        }
        // ...
    }
}

interface DiscountStrategy {
    public int getDiscount();
}

class DiscountStrategy1 implements DiscountStrategy {
    public int getDiscount() {
        // calculate & return discount;
    }
}

class DiscountStrategy2 implements DiscountStrategy {
    public int getDiscount() {
        // calculate & return discount;
    }
}

class DiscountStrategy3 implements DiscountStrategy {
    public int getDiscount() {
        // calculate & return discount;
    }
}

Can you please help me understand this concept with better implementation of this example?

Author:user1298426,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/48377525/replace-conditional-with-polymorphism
Oleksandr Pyrohov :

I think that Product class must not be aware about the discount creation process, it should only use a discount. So, my suggestion is to create a discount factory with a Map that will hold different discount implementations:\n\nclass DiscountFactory {\n private static final Map<String, DiscountStrategy> strategies = new HashMap<>();\n private static final DiscountStrategy DEFAULT_STRATEGY = () -> 0;\n\n static {\n strategies.put(\"code1\", () -> 10);\n strategies.put(\"code2\", () -> 20);\n }\n\n public DiscountStrategy getDiscountStrategy(String priceCode) {\n if (!strategies.containsKey(priceCode)) {\n return DEFAULT_STRATEGY;\n }\n return strategies.get(priceCode);\n }\n}\n\n\nAfter that, the Product class can be simplified:\n\nclass Product {\n private DiscountStrategy discountStrategy;\n\n Product(DiscountStrategy discountStrategy) {\n this.discountStrategy = discountStrategy;\n }\n\n public int getDiscount() {\n return discountStrategy.getDiscount();\n }\n}\n\n\nFunctional interface will allow you to create different implementations using lambda expressions:\n\ninterface DiscountStrategy {\n int getDiscount();\n}\n\n\nAnd finally, example of the use of a product together with discount:\n\nDiscountFactory factory = new DiscountFactory();\nProduct product = new Product(factory.getDiscountStrategy(\"code1\"));\n",
2018-01-22T09:23:01
akshaya pandey :

My two cents:\nYou will need to pass the parameters to discount() method.\n\na. Create a static class level HashMap of DiscountStrategy.\nE.g :\n\nmap.put(\"CODE1\", new DiscountStrategy1());\nmap.put(\"CODE2\", new DiscountStrategy2());\n\n\nb. wherever you need, you can simply use:\n\nmap.get(priceCode).discount()\n",
2018-01-22T08:44:40
Mars Moon :

Here is what you need to do\n\n class Product {\n\n String priceCode;\n DiscountStrategy discountStrategy;\n\n HashMap<String, DiscountStrategy> map=new HashMap();\n\n Product(String priceCode) {\n map.put(\"CODE1\", new DiscountStrategy1());\n map.put(\"CODE2\", new DiscountStrategy2());\n map.put(\"CODE3\", new DiscountStrategy3());\n setDiscount(priceCode);\n }\n\n public void setDiscount(String priceCode){\n discountStrategy=map.get(priceCode);\n }\n\n public int getDiscount() {\n return discountStrategy.getDiscount();\n }\n}\n",
2018-01-22T08:51:26
yy