用多态性替换条件

2022-09-01 14:24:44

我试图通过一个例子来理解这个干净的代码实践。考虑一个具有折扣开关案例的类产品。我正在尝试用多态性替换 switch 语句。

代码之前:

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;
        }
    }
}

在下面的代码中,您可以看到我删除了switch语句,但我仍然有条件创建折扣策略的对象。我的问题是,我仍然有我试图用多态性消除的如果条件。

代码后:

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;
    }
}

您能帮助我更好地实现此示例来理解此概念吗?


答案 1

我认为产品类一定不知道折扣创建过程,它应该只使用折扣。因此,我的建议是创建一个具有Map的折扣工厂,该地图将包含不同的折扣实现:

class DiscountFactory {
    private static final Map<String, DiscountStrategy> strategies = new HashMap<>();
    private static final DiscountStrategy DEFAULT_STRATEGY = () -> 0;

    static {
        strategies.put("code1", () -> 10);
        strategies.put("code2", () -> 20);
    }

    public DiscountStrategy getDiscountStrategy(String priceCode) {
        if (!strategies.containsKey(priceCode)) {
            return DEFAULT_STRATEGY;
        }
        return strategies.get(priceCode);
    }
}

之后,可以简化 Product 类:

class Product {
    private DiscountStrategy discountStrategy;

    Product(DiscountStrategy discountStrategy) {
        this.discountStrategy = discountStrategy;
    }

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

功能接口将允许您使用 lambda 表达式创建不同的实现:

interface DiscountStrategy {
    int getDiscount();
}

最后,使用产品与折扣一起使用的示例:

DiscountFactory factory = new DiscountFactory();
Product product = new Product(factory.getDiscountStrategy("code1"));

答案 2

我的两分钱:您需要将参数传递给方法。discount()

一个。创建 的静态类级哈希映射。例如:DiscountStrategy

map.put("CODE1", new DiscountStrategy1());
map.put("CODE2", new DiscountStrategy2());

b. 无论您需要什么,您都可以简单地使用:

map.get(priceCode).discount()

推荐