Spring设计模式-实战篇之策略模式 + 工厂模式

案例:使用策略模式和工厂模式优化大量的if-else

        原先代码如下,有衣服、零食、蔬菜三种类型的商品,并且每一类满减折扣不一样,如果使用if-else,代码会显得非常冗长,并且大量的if-else很容易眼花导致维护代码时改错地方,不利于后期维护和扩展。

 public static double calculatePrice(String type, double price) {
        if ("cloth".equals(type)) {
            if (price > 1000) {
                return price * 0.7;
            } else if (price > 800) {
                return price * 0.75;
            } else if (price > 600) {
                return price * 0.8;
            } else if (price > 500) {
                return price * 0.85;
            } else if (price > 300) {
                return price * 0.88;
            } else if (price > 200) {
                return price * 0.9;
            } else {
                return price;
            }
        } else if ("snacks".equals(type)) {
            if (price > 500) {
                return price * 0.8;
            } else if (price > 300) {
                return price * 0.85;
            } else if (price > 200) {
                return price * 0.88;
            } else {
                return price;
            }
        } else if ("vegetable".equals(type)) {
            if (price > 200) {
                return price * 0.8;
            } else if (price > 100) {
                return price * 0.88;
            } else if (price > 50) {
                return price * 0.95;
            } else {
                return price;
            }
        }
        return price;
    }

使用策略模式优化:

废话不多说,直接上代码

1、首先定义一个价格计算策略接口

public interface PriceCalculationStrategy {
    double calculatePrice(double price);
}

2、衣物价格计算策略实现类

public class ClothPriceCalculationStrategy implements PriceCalculationStrategy {
    @Override
    public double calculatePrice(double price) {
        if (price > 1000) {
            return price * 0.7;
        } else if (price > 800) {
            return price * 0.75;
        } else if (price > 600) {
            return price * 0.8;
        } else if (price > 500) {
            return price * 0.85;
        } else if (price > 300) {
            return price * 0.88;
        } else if (price > 200) {
            return price * 0.9;
        } else {
            return price;
        }
    }
}

当然这里如果你不想使用大量的if-else,也可以使用Map,因为Map也是一种类似于策略模式的思想,这里的Map是在静态代码块进行属性设置的,优点如下:

  1. 采用空间换取时间的思想后,Map在程序启动之后即可预先赋值。当然不必担心内存溢出的问题,自JDK 8以后,方法区的实现类是元空间,其内存存在于实际内存中,而非JVM。因此,new几个对象占用的空间犹如沧海一粟;
  2. 可以把key, value像枚举一样一行行写出来,易于修改。

具体实现如下:

public class ClothPriceCalculationStrategy implements PriceCalculationStrategy {
    private static final Map<Integer, Double> DISCOUNT_MAP = new HashMap<>();

    static {
        DISCOUNT_MAP.put(1000, 0.7);
        DISCOUNT_MAP.put(800, 0.75);
        DISCOUNT_MAP.put(600, 0.8);
        DISCOUNT_MAP.put(500, 0.85);
        DISCOUNT_MAP.put(300, 0.88);
        DISCOUNT_MAP.put(200, 0.9);
    }

    @Override
    public double calculatePrice(double price) {
        for (int threshold : DISCOUNT_MAP.keySet()) {
            if (price > threshold) {
                return price * DISCOUNT_MAP.get(threshold);
            }
        }
        return price;
    }
}

 3、零食价格计算策略实现类

public class SnacksPriceCalculationStrategy implements PriceCalculationStrategy {
    @Override
    public double calculatePrice(double price) {
        if (price > 500) {
            return price * 0.8;
        } else if (price > 300) {
            return price * 0.85;
        } else if (price > 200) {
            return price * 0.88;
        } else {
            return price;
        }
    }
}

4、 蔬菜价格计算策略实现类

public class VegetablePriceCalculationStrategy implements PriceCalculationStrategy {
    @Override
    public double calculatePrice(double price) {
        if (price > 200) {
            return price * 0.8;
        } else if (price > 100) {
            return price * 0.88;
        } else if (price > 50) {
            return price * 0.95;
        } else {
            return price;
        }
    }
}

5、测试,通过new不同的策略,传入价格即可计算。 

public class test {
    public static void main(String[] args) {

        // ---通过new不同的策略实现类进行计算价格---

        // 衣物类满减策略
        PriceCalculationStrategy clothPriceCalculationStrategy = new ClothPriceCalculationStrategy();
        System.out.println(clothPriceCalculationStrategy.calculatePrice(1738));

        // 食品类满减策略
        PriceCalculationStrategy snacksPriceCalculationStrategy = new SnacksPriceCalculationStrategy();
        System.out.println(snacksPriceCalculationStrategy.calculatePrice(375));

        // 蔬菜类满减策略
        PriceCalculationStrategy vegetablePriceCalculationStrategy = new VegetablePriceCalculationStrategy();
        System.out.println(vegetablePriceCalculationStrategy.calculatePrice(77));
    }
}

当然,我们可以使用工厂模式进一步优化

也就是通过工厂统一管理,直接new 一个工厂传参即可,直接上代码:

1、创建价格计算工厂策略类

public class PriceCalculationStrategyFactory {
    private static final Map<String, PriceCalculationStrategy> strategyMap = new HashMap<>();

    static {
        strategyMap.put("cloth", new ClothPriceCalculationStrategy());
        strategyMap.put("snacks", new SnacksPriceCalculationStrategy());
        strategyMap.put("vegetable", new VegetablePriceCalculationStrategy());
    }

    public double calculatePrice(String type, double price) {
        PriceCalculationStrategy strategy = strategyMap.get(type);
        if (strategy != null) {
            return strategy.calculatePrice(price);
        }
        return price;
    }
}

 2、测试,通过new一个工厂,传入类型和价格即可。 

public class test {
    public static void main(String[] args) {
        PriceCalculationStrategyFactory factory = new PriceCalculationStrategyFactory();
        double cloth = factory.calculatePrice("cloth", 1738);
        double snacks = factory.calculatePrice("snacks", 375);
        double vegetable = factory.calculatePrice("vegetable", 77);
        System.out.println("满减计算后,衣服价格:" + cloth);
        System.out.println("满减计算后,零食价格:" + snacks);
        System.out.println("满减计算后,蔬菜价格:" + vegetable);
    }
}

总结

  1. 对于大量的if-else,特别是大量的嵌套的if-else,可以用策略模式+工厂模式优化,少量的if-else就没必要了;
  2. 使用设计模式,将会增加代码量,但是解耦性特别强,代码更加清晰易懂,而且具有更强的扩展性和维护性。
  3. 策略模式将不同的责任分配到不同的类中,实现单一职责原则,提高代码的内聚性。

ps:以下是我整理的java面试资料,感兴趣的可以看看。最后,创作不易,觉得写得不错的可以点点关注!

链接:https://www.yuque.com/u39298356/uu4hxh?# 《Java面试宝典》 

  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值