设计模式系列:搞懂策略模式,自由选择策略

策略模式(Strategy)的定义:定义一系列的算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响客户端的调用。属于行为型模式。

策略模式的本质是通过对算法的封装,把算法的使用和算法的实现隔离,并委派给不同的对象对这些算法进行分别管理。

策略模式的结构:策略模式主要有3种角色。

  1. 抽象策略(Strategy)类:定义了一个公共接口,规定策略或算法的行为方法,一般使用接口或抽象类实现。
  2. 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
  3. 上下文环境(Context)类:供客户端调用的类,持有一个策略类的引用,委派给策略类进行实际业务处理。

策略模式的通用实现:

//抽象策略类
public interface Strategy {
    void strategyMethod();
}

//具体策略A
public class ConcreteStrategyA implements Strategy{
    @Override
    public void strategyMethod() {
        System.out.println("执行具体策略A的策略方法!");
    }
}

//具体策略B
public class ConcreteStrategyB implements Strategy{
    @Override
    public void strategyMethod() {
        System.out.println("执行具体策略B的策略方法!");
    }
}

//上下文环境类
public class Context {
    private Strategy strategy;

    public Context(Strategy strategy){
        this.strategy = strategy;
    }

    public void strategyMethod() {
        strategy.strategyMethod();
    }
}

//测试类
public class StrategyTest {
    public static void main(String[] args) {
        Context contextA = new Context(new ConcreteStrategyA());
        contextA.strategyMethod();

        Context contextB = new Context(new ConcreteStrategyB());
        contextB.strategyMethod();
    }
}

策略模式的结构图:

策略模式的应用实例:现在交通发达,给我们的出行带来了极大的便利,我们可以选择飞机、火车、汽车等等,我们就以出行的交通方式为例,使用策略模式来实现。

//交通方式接口
public interface ITransport {
    void goOut();
}

//飞机
public class Plane implements ITransport{
    @Override
    public void goOut() {
        System.out.println("远距离出行,选择飞机!!!");
    }
}

//火车
public class Train implements ITransport{
    @Override
    public void goOut() {
        System.out.println("中等距离出行,选择高铁!!!");
    }
}

//汽车
public class Car implements ITransport{
    @Override
    public void goOut() {
        System.out.println("近距离出行,选择汽车!!!");
    }
}

//出行方式枚举类
public enum TransportType {
    CAR, TRAIN, PLANE;
}

//策略管理类
public class TransportStrategy {
    private static Map<TransportType, ITransport> strategy = new HashMap<>();

    static {
        strategy.put(TransportType.CAR,new Car());
        strategy.put(TransportType.TRAIN,new Train());
        strategy.put(TransportType.PLANE,new Plane());
    }

    public ITransport getTransport(TransportType transportType){
        if(transportType == null){
            throw new RuntimeException("交通方式选择有误!");
        }
        return strategy.get(transportType);
    }
}

//测试类
public class Test {
    public static void main(String[] args) {
        TransportStrategy strategy = new TransportStrategy();
        ITransport transport = strategy.getTransport(TransportType.PLANE);
        transport.goOut();
    }
}

策略模式在源码中的应用:Jdk中的Comparator比较器接口、Spring中的Resource接口都是采用的策略模式实现的。

策略模式的优点:

  1. 使用策略模式可以避免使用多重条件语句,如 if...else 语句、switch...case 语句。
  2. 策略模式可以把算法族的公共代码转移到父类中实现,提高代码复用性。
  3. 策略模式可以在不修改原代码的情况下,灵活增加新算法,符合开闭原则。
  4. 策略模式把算法的使用和实现隔离,提高算法的保密性和安全性。

策略模式的缺点:

  1. 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。
  2. 策略模式造成很多的策略类,增加维护难度。

策略模式的使用场景:

  1. 同一类型问题有多种独立的处理算法,可将每个算法封装到策略类中。
  2. 系统中各算法彼此独立,且要求对客户端隐藏具体算法的实现细节。
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风雨编码路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值