策略模式
1.策略模式介绍
策略模式,定义了算法家族,将它们分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
简单来说,策略模式就是有一个抽象类,这个抽象类中定义了一些抽象方法。具体的策略类继承这个抽象类,并根据自己的业务需要分别实现自己的具体方法业务逻辑。
当具体策略类都实现自己的具体方法业务后,我们还需要实现一个Context上下文类,以此类对各个具体的策略类进行一个包装。客户端使用具体策略类的时候,给Context传入具体的策略类型,由Context负责执行具体策略类的业务方法,以达到当算法变化时,不同策略类的更换,不会影响到客户端的目的。
2.策略模式代码示例
下面以一个简单的案例来展示策略模式的使用
2.1Strategy抽象类
/**
* 抽象策略类
*/
public abstract class Strategy {
public abstract void method();
}
2.2具体策略类A
/**
* Strategy抽象类的具体策略实现类A
*/
public class ConcreteStrategyA extends Strategy{
@Override
public void method() {
System.out.println("算法A的实现");
}
}
2.3具体策略类B
/**
* Strategy抽象类的具体策略实现类B
*/
public class ConcreteStrategyB extends Strategy{
@Override
public void method() {
System.out.println("算法B的实现类");
}
}
2.4具体策略类C
/**
* Strategy抽象类的具体策略实现类C
*/
public class ConcreteStrategyC extends Strategy{
@Override
public void method() {
System.out.println("算法C的具体实现");
}
}
2.5Context上下文类
/**
* Context上下文类,用于封装Strategy抽象类
* 的方法,达到具体策略类变化而不影响客户端的目的
*/
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void contextInterface(){
strategy.method();
}
}
2.6主方法测试类
public class MainApplication {
public static void main(String[] args) {
// 声明一个Context上下文对象
Context context;
// 给上下文对象传入A策略
context = new Context(new ConcreteStrategyA());
context.contextInterface();
// 给上下文对象传入B策略
context = new Context(new ConcreteStrategyB());
context.contextInterface();
// 给上下文对象传入C策略
context = new Context(new ConcreteStrategyC());
context.contextInterface();
}
}
运行结果
算法A的实现
算法B的实现类
算法C的具体实现
3.策略模式UML类图
4.策略模式优缺点
4.1优点
- 策略模式提供了对“开闭原则”的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活增加新的算法或行为
- 策略模式提供了管理相关的算法家族的方法
- 策略模式提供了可以替换继承关系的办法
- 使用策略模式可以避免使用多重条件语句
4.2缺点
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类
- 策略模式将产生很多的策略类,使用时新建的对象数量可能会比较多
5.策略模式适用场景
- 在一个系统里有许多类,他们之间的区别仅在于它们的行为,那么使用策略模式可以动态的让一个对象在许多行为中选择一种
- 一个系统需要动态的在几种算法中选择一种
- 如果一个对象有很多的行为,如果不用恰当的面试,这些行为就只好使用多重的条件语句来实现
- 不希望客户端知道复杂的、与算法相关的数据结构,在具体策略类中封装算法和相关的数据结构,提高算法的保密性和安全性
例如:电商网站的支付方式,银联、微信、支付宝等就可以使用策略模式来实现
6.总结
策略模式在代码实现结构上,和简单工厂模式有相似之处,所以大部分人看到这两种模式,容易产生混乱。其实就使用上来说,两种模式都可以使用,也都能实现同一个目标,只要注意代码结构,谨慎小心,防止改动原有逻辑即可。
但是其实这两个模式还是有细微差别的
- 简单工厂模式,使用的时候,是向工厂类传入一个条件,工厂类根据条件,生成相应的对象,并返回给客户端
- 策略模式,使用的时候,客户端会实例化一个Context上下文对象,然后将需要使用的具体策略类实例对象作为参数传给上下文对象,客户端通过调用Context上下文对象的某个方法,得到所需结果;
- 然后简单工厂模式属于创建型模型,它的作用是创建对象。策略模式是行为模型,作用是在许多行为中选择一种行为,并执行这种行为;
- 解决的问题不同,简单工厂模式是解决资源的统一分发,将对象的实例化和客户端解耦。策略模式是为了解决策略的切换和扩展;