二、12【设计模式】之策略模式

今天的博客主题

       设计模式 ——》 设计模式之策略模式


策略模式 SP (Strategy Pattern)

 

概念

策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。

定义一组算法(业务逻辑),将每个算法都封装起来,并且使它们之间可以互换。

所主要解决的问题是在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。

 

简答说就是定义了算法家族,分别封装起来,它们之间可以互相替换,此模式变化独立于算法的使用者。

 

应用场景

1)针对同一类型的问题,有多种处理方式,每一个种都能独立解决问题。

2)算法需要自由切换场景。

3)需要屏蔽算法规则的场景。

4)

策略模式在生活中的场景也很多,比如我们的阶梯个税,支付方式(微信、支付宝、银联)。

 

优点

1)算法可以自由切换。

2)避免使用多重条件判断。

3)扩展性良好。

4)符合开闭原则。

5)提高算法的保密性及安全性

6)

 

缺点

1)系统的策略类会增多。

2)客户端必须知道所有策略,自行决定使用那种策略。

3)

只要你的需求中有说在不同的时间或者场景下要有不同的业务规则,就可以考虑使用策略模式来处理这种变化。

 

源码中的应用

java.util.Comparator
org.springframework.beans.factory.support.InstantiationStrategy

 

代码示例

策略模式里面的三个角色

上下文角色(Context):用来操作策略的上下文环境,屏蔽高层模块(客户端)对策略,算法的直接访问,封装可能存在的变化

抽象策略角色(Strategy):规定策略或算法的行为

具体策略角色(ConcreteStrategy):具体的策略或算法实现

策略模式的职责就是隔离客户端与策略类的耦合,让客户端完全与上下文环境沟通,无需关心具体策略。

// 生活场景:不同VIP等级的折扣不同
// 依照这个场景,写出来的代码可能会像这个样子
class vipDiscount{
    public double getPrice(String vipLevel, double price){
        if("V1".equals(vipLevel)){
            return price * 0.98;
        }else if("V2".equals(vipLevel)){
            return price * 0.93;
        }else if("V3".equals(vipLevel)){
            return price * 0.88;
        }
        return price;
    }
}

// 使用策略模式重构代码,消除if...else...
// 定义抽象策略算法类
abstract class AbstractStrategy{
    abstract double algorithm(double price);
}

// 定义每一种算法的类,作为抽象策略类的子类
class V1ConcreteStrategy extends AbstractStrategy {
    @Override
    double algorithm(double price) {
        return price * 0.98;
    }
}
class V2ConcreteStrategy extends AbstractStrategy {
    @Override
    double algorithm(double price) {
        return price * 0.93;
    }
}
class V3ConcreteStrategy extends AbstractStrategy {
    @Override
    double algorithm(double price) {
        return price * 0.88;
    }
}

// 定义上下文角色,负责和具体的策略类交互
class Context{
    // 这种写法消除不了if..else..
//    AbstractStrategy strategy;
//
//    public Context(AbstractStrategy strategy) {
//        this.strategy = strategy;
//    }
//
//    public double getPrice(double price){
//        return strategy.algorithm(price);
//    }

    // 定义一个算法族,将算法策略封装
    static Map<String, AbstractStrategy> strategyMap = new HashMap<>();

    static {
        strategyMap.put("V1", new V1ConcreteStrategy());
        strategyMap.put("V2", new V2ConcreteStrategy());
        strategyMap.put("V3", new V3ConcreteStrategy());
    }

    public double getPrice(String vipLevel, double price){
        if(strategyMap.containsKey(vipLevel)){
            return strategyMap.get(vipLevel).algorithm(price);
        }
        return price;
    }
}

// 客户端调用
public class StrategyPattern {
    public static void main(String[] args) {
        vipDiscount vipDiscount = new vipDiscount();
        double v1 = vipDiscount.getPrice("V1", 138);
        System.out.println("VIP 1 优惠价:" + v1);

        Context context = new Context();
        double v1Price = context.getPrice("V1", 138);
        System.out.println("VIP 1 优惠价:" + v1Price);
    }
}

// 输出结果
VIP 1 优惠价:135.24
VIP 1 优惠价:135.24

如果不用策略模式,在需求扩展时候,要在 vipDiscount 的 getPrice() 方法增加逻辑判断以及对饮的算法。当使用了策略之后,在家需求,增加策略类,在算法族的数据结构增加对应策略即可。

 

注意

如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值