一、策略模式
策略模式(Strategy),定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换。比如出行方式,可以选择骑自行车、坐公交车、打车、开车等等,每种出行方式都是一个策略。
二、策略模式的应用
1.使用场景
针对同一类型的问题,有多种处理方式,每一种都能独立解决问题且区分它们的只是它们直接的行为。算法需要自由切换的场景。需要屏蔽算法规则的场景。
2.使用方式
strategy类,定义所有支持的算法的公共接口。
concreteStrategy,封装具体的方法或行为,继承strategy类。
context,用一个concreteStrategy来配置,维护一个对strategy的引用。
简单工厂或枚举类生成Context对象。
3.主要解决
有多种算法相似的情况下,大量使用if else为程序带啦的负责性和臃肿性。
4.优点
算法的多样性,且具备自由切换场景。有效避免多重条件判断,增强了封装性,简化的操作,降低出错概率。扩展性良好,策略类遵循里氏替换原则,可以很方便的进行策略扩展。
5.缺点
策略类数量增多,每个策略都是一个类,复用的可能性很小。所有策略类必须对外暴露,以便客户端能够选择。
6.注意事项
如果一个系统的策略多于四个,就需要考虑使用混合模式来解决策略膨胀的问题。
三、策略模式的实现
1.strategy
public abstract class Strategy {
public abstract void AlgorithmInterface();
}
2.concreteStrategy
public class ConcreteStrategyA extends Strategy {
@Override
public void AlgorithmInterface() {
System.err.println("ConcreteStrategyA的实现");
}
}
public class ConcreteStrategyB extends Strategy {
@Override
public void AlgorithmInterface() {
System.err.println("ConcreteStrategyB的实现");
}
}
public class ConcreteStrategyC extends Strategy {
@Override
public void AlgorithmInterface() {
System.err.println("ConcreteStrategyC的实现");
}
}
3.context
public class Context {
private Strategy strategy;
Context(Strategy strategy){
this.strategy = strategy;
}
public void contextInterface(){
strategy.AlgorithmInterface();
}
}
4.StrategyFactory
public class StrategyFactory {
public static Context create(Integer type){
Context context = null;
switch (type) {
case 1:
context = new Context(new ConcreteStrategyA());
break;
case 2:
context = new Context(new ConcreteStrategyB());
break;
case 3:
context = new Context(new ConcreteStrategyC());
break;
}
return context;
}
}
public enum StrategyEnum {
ConcreteStrategyA {
@Override
public Context create() {
return new Context(new ConcreteStrategyA());
}
},
ConcreteStrategyB {
@Override
public Context create() {
return new Context(new ConcreteStrategyA());
}
},
ConcreteStrategyC {
@Override
public Context create() {
return new Context(new ConcreteStrategyA());
}
};
public abstract Context create();
}
5.StrategyClient
public class StrategyClient {
public static void main(String[] args) {
Context context;
//策略模式 中的上下文环境(Context),其职责本来是隔离客户端与策略类的耦合,
//让客户端完全与上下文环境沟通,无需关系具体策略
/**
* 传统方式
* 客户端内部直接自己指定要哪种策略(new Context(new ConcreteStrategyA())),
* 客户端与具体策略类耦合了,
* 而上下文环境在这里起的作用只是负责调度执行,获取结果,并没有完全起到隔离客户端与策略类的作用。
*/
context = new Context(new ConcreteStrategyA());
context.contextInterface();
context = new Context(new ConcreteStrategyB());
context.contextInterface();
context = new Context(new ConcreteStrategyC());
context.contextInterface();
/**
* 简单工厂
* 可以通过简单工厂模式将具体策略的创建与客户端进行隔离
*/
context = StrategyFactory.create(1);
context.contextInterface();
context = StrategyFactory.create(2);
context.contextInterface();
context = StrategyFactory.create(3);
context.contextInterface();
/**
* 枚举
* 通过策略枚举将上下文环境与具体策略类融合在一起,简化代码。
* 当具体策略相对稳定时,推荐使用策略枚举。
*/
context = StrategyEnum.ConcreteStrategyA.create();
context.contextInterface();
context = StrategyEnum.ConcreteStrategyB.create();
context.contextInterface();
context = StrategyEnum.ConcreteStrategyC.create();
context.contextInterface();
}
}
来源:CSDN
作者:破小叶
链接:https://blog.csdn.net/qq_23586657/article/details/103576685