设计模式之策略者模式
1.定义/概念
策略模式,定义了一系列的算法,将每种算法封装起来并可以相互替换使用,策略模式让算法独立于使用它的客户应用而独立变化。
策略模式是处理算法的不同变体的一种行为模式,通过在抽象策略中定义算法接口或封装算法标识,实现该抽象策略的具体子类成为一个单独的算法,及具体策略。。策略模式使用多个类来区别不同的行为,使用策略模式避免暴露负责的、与算法相关的内部数据结构,当一个类中的操作以多个条件分支语句的形式出现的时候,可以使用策略模式将相关的条件分支移入各自的具体策略类以代替这些条件语句,从而减少系统处理的复杂度。
定义的分析
策略模式定义和封装了一系列的算法,他们是可以相互替换的也就是说他们具有共性,而他们的共性就是体现在策略接口的行为上,另外为了达到最后一句话的目的,也就是说让算法独立于使用它的客户而独立变化,我们需要让客户端依赖于策略接口。
2.角色和组成
环境类(Context):同一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据
抽象策略类(Strategy):定义所有支持的算法的公共接口。Context使用这个接口来调用某ConcreteStrategy定义的算法
具体策略类(ConcreteStrategy):以Strategy接口实现某具体算法
3.例子分析
StrategyDemo
package com.glut.demo;
/**
* 使用 Context 实例 来查看当它改变策略Strategy时的行为变化
* @author qichunlin
*
*/
public class StrategyDemo {
public static void main(String[] args) {
//创建环境类 承接上下文
Context context = new Context(new StrategyOperationAdd());
System.out.println("10 + 5 ="+context.executeStrategy(10, 5));
//环境类中创建具体减法策略类
context = new Context(new StrategyOperationSubstract());
System.out.println("10 - 5 = "+context.executeStrategy(10, 5));
context = new Context(new StrategyOperationMultiply());
System.out.println("10 * 5= "+context.executeStrategy(10, 5));
}
}
Strategy.java (策略接口)
package com.glut.demo;
/**
* 创建一个接口
*
* 抽象策略类
* @author qichunlin
*
*/
public interface Strategy {
//操作方法,里面传入两个数
public int doOperation(int num1,int num2);
}
StrategyOperationAdd.java (具体策略类)
package com.glut.demo;
/**
* 具体策略(实现两个数相加)
* 创建实现接口的实体类
* @author qichunlin
*
*/
public class StrategyOperationAdd implements Strategy{
@Override
public int doOperation(int num1, int num2) {
int num = num1+num2;
return num;
}
}
StrategyOperationSubstract.java (具体策略类)
package com.glut.demo;
/**
* 具体策略类 实现相减功能
* 创建实现接口的实体类
* @author qichunlin
*
*/
public class StrategyOperationSubstract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
int num = num1 - num2;
return num;
}
}
StrategyOperationMultiply.java (具体策略类)
package com.glut.demo;
/**
* 具体策略类 实现两个数相乘的功能
* 创建实现接口的实体类
*
* @author qichunlin
*
*/
public class StrategyOperationMultiply implements Strategy{
@Override
public int doOperation(int num1, int num2) {
int num = num1 * num2;
return num;
}
}
Context.java (环境类)
package com.glut.demo;
/**
* 环境角色类 上下文承接
* 定义接口来访问里面的数据
*
* @author qichunlin
*
*/
public class Context {
//持有一个具体策略的对象
private Strategy strategy;
//通过构造方法传入一个具体的对象;具体策略对象
public Context(Strategy strategy) {
this.strategy = strategy;
}
//策略方法
public int executeStrategy(int num1,int num2){
int st = strategy.doOperation(num1, num2);
return st;
}
}
4.策略模式使用场景
(1)针对同一类型问题的多种处理方式仅仅是具体行为有差别时;或者这么理解:如果一个系统类里面有许多类,他们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
需要安全地封装多种同一类型的操作时;
(2)出现统一抽象类有多个子类,而又需要使用if-else 或者 switch-case 来选择具体子类时
(3)如果一个对象会有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择来实现
注意:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀问题。
5.策略模式的优缺点分析
优点
可以动态的改变对象的行为
算法可以自由切换
避免使用多重条件判断
扩展性良好
缺点
客户端必须知道所有策略者类,并自行决定使用哪一个策略类;
策略模式将造成产生很多策略类,策略类会增多