策略模式 Strategy
与策略相关的常见词汇有:营销策略、折扣策略、教学策略、记忆策略、学习策略....
“策略”意味着分状况讨论,而不是一律而论
面对不一样年龄段的人,面对不一样的商品,必然将会有不一样的话术;
面对购物总价的范围,极可能会有不一样的折扣方案;
面对理解能力不一样的学生,必然有不一样的教学策略;
而在咱们程序的世界里,“策略”就是分状况讨论。也就是
相似状态模式中的条件分支或者选择分支。
只不过
状态模式中是事物的不一样状态,而策略模式中关注的是处理方法。
好比
if(totalPrice > 1000){
//9折
else if(totalPrice > 2000){
//8折
}else if(totalPrice > 3000){
//7折
}
这就是一种打折策略,对应于购物总金额的不一样,采用不一样的处理方法。
显然,使用条件分支或者选择语句,相似状态模式中的分析,也存在相似的问题
若是条件过多,会致使
处理逻辑复杂
并且,策略的逻辑与业务逻辑
耦合在一块儿,若是处理方法变化还须要修改业务逻辑方法,
扩展性差
并且,也
不适合增长新的策略方案
意图
定义一系列的算法,把他们一个个的封装起来,并使他们能够互相转换,本模式使得算法能够独立于使用它的客户端而变化。
别名:政策Policy
策略模式与状态模式本质同样,只不过一个是状态,一个是行为算法。
结构
抽象策略角色Strategy
定义了抽象的策略,好比打折,排序等
定义了策略的一致性访问接口,好比定义了一个排序接口 sort()
具体策略角色ConcreteStrategy
实现抽象策略的定义的接口,实现本身的行为算法,好比ConcreteStrategyA冒泡 ConcreteStrategyB快排
环境类Context
维护Strategy,持有一个Strategy的引用,用来管理Strategy,能够切换策略
是Strategy的使用者
代码示例
排序接口,定义了一个sort方法
package strategy;
public interface SortStrategy {
void sort();
}
package strategy;
public class Bubble implements SortStrategy {
@Override
public void sort() {
System.out.println("冒泡排序,输出结果...");
}
}
package strategy;
public class QuickSort implements SortStrategy {
@Override
public void sort() {
System.out.println("快速排序,输出结果...");
}
}
环境类
内部持有一个SortStrategy,简单起见初始化为Bubble
使用一个简单的方法进行切换
而且提供sort方法,代理strategy的sort方法
package strategy;
public class Context {
private SortStrategy strategy = new Bubble();
public void setStrategy(String strategy) {
if(strategy.equals("bubble")){
this.strategy = new Bubble();
}else if(strategy.equals("quick")){
this.strategy = new QuickSort();
}
}
public void sort() {
strategy.sort();
}
}
测试方法
package strategy;
public class Test {
public static void main(String[] args) {
Context context = new Context();
context.sort();
context.setStrategy("quick");
context.sort();
context.setStrategy("bubble");
context.sort();
}
}
上面的代码能够看得出来,具体的算法行为,被封装在了具体的策略类中,好比Bubble和QuickSort
经过环境类Context对算法进行管理切换。
总结
策略模式与状态模式是相似的,借助于多态的特性,以达到不一样状态不一样行为
不一样的场景使用不一样的算法,这本就是一种“不一样状态,不一样行为”的含义延伸
都是借助于多态特性,进而也就是依赖倒置原则---面向抽象编程,其根本也是为了“低耦合”。
策略模式中使用独立的类来封装不一样的算法行为,每个类封装具体的行为
策略模式主要是将
算法的定义与使用进行分开,算法被封装在不一样的策略类中
借助于算法的环境类Context,针对抽象策略进行编程,符合依赖倒置原则
并且,新增长具体的算法,只须要增长一个新的具体的策略类便可。
策略模式将算法的定义与使用分开,具体的策略彻底能够经过配置文件等方式注入到Context中,客户端彻底不须要关注具体的策略
并且,
运行时能够随时的更换策略
策略模式的Context,咱们的示例中一个Context一个当前策略,那么Context到底内部维护几个策略?到底谁负责切换,是客户端仍是Context
我的认为都是灵活的,策略模式的核心就在于算法的定义与使用的解耦,在接下来的其余事情,本身看状况随便来(随便的前提是合理有效)
只要是涉及到
多种算法行为的
切换:策略能够运行时切换
复用:算法与使用解耦,算法能够单独扩展
封装:屏蔽使用者对算法内部数据结构等逻辑的了解,不然若是算法的实现耦合在客户端,客户端不是一清二楚么
都
能够考虑策略模式,策略模式可以灵活的切换算法,以及算法独立发展,符合开闭原则
可是相似状态模式,策略模式也会产生不少小的具体的策略类,增长类的个数和运行时对象的个数。