一、概念与介绍
定义
通过定义一系列封装好的算法,使得它们能以不同的实现去完成相同的工作,相互之间可以进行替换。 策略模式属于行为型模式,它通过对算法进行封装,委派给不同的对象来对这些算法进行管理,将算法的责任和实现进行了分割。
应用场景
在实践中发现,策略模式不止可以用来封装算法,还可以封装几乎任何类型的规则。只要是需要在不同情况下应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。
应用举例
1.存储目标数据,到底是用数组,还是用链表。又或者,使用二叉树...
2.早餐是吃榨菜包、吃蒸饺,还是吃红糖馒头。
主要优点
1.当不同的行为堆砌在一个类中时,经常需要使用条件语句来选择合适的行为,将这些行为封装在一个个独立的Strategy类中,就可以在使用这些行为的类中消除条件语句(扩展性、可维护性好,可以减少判断语句的使用)。
2.策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码
3.策略模式把算法的使用放到Context环境类中,而算法的实现移到具体策略类中,实现了二者的分离。
主要缺点
1.策略类会很多,且所有的策略类都需要对外暴露。
2.客户端必须理解所有策略算法的区别,以便选择恰当的算法类。
二、结构与实现
模式的结构
模式的实现
//抽象策略类
interface Strategy {
public void strategyMethod(); //策略方法
}
//具体策略类A
class ConcreteStrategyA implements Strategy {
public void strategyMethod() {
System.out.println("执行策略A:从蒸笼里拿一份蒸饺");
}
}
//具体策略类B
class ConcreteStrategyB implements Strategy {
public void strategyMethod() {
System.out.println("执行策略B:从蒸笼里拿一个红糖馒头");
}
}
//环境类
class Context {
private Strategy strategy;
public void startStrategy(Strategy strategy) {
this.strategy = strategy;
strategy.strategyMethod();
}
}
//策略模式
public class StrategyPattern {
public static void main(String[] args) {
Context c = new Context();
//执行策略A
Strategy strategyA = new ConcreteStrategyA();
c.startStrategy(strategyA);
System.out.println("-----------------");
//执行策略B
Strategy strategyB = new ConcreteStrategyB();
c.startStrategy(strategyB);
}
}
程序运行结果
执行策略A:从蒸笼里拿一份蒸饺
-----------------
执行策略B:从蒸笼里拿一个红糖馒头
这里的环境类Context可以理解为早餐店,但是我们(客户端)却要自己从蒸笼里找到对应的食物。感觉有点不对劲啊。
三、策略工厂模式(拓展)
前面说过,策略模式的缺点之一就是“客户端必须理解所有策略算法的区别,以便选择恰当的算法类”。当算法类越来越多,客户端的工作就愈加困难了...
那么,能不能把这些判断的过程从客户端转移到其他地方呢?这时就要考虑到我们的环境类Context了。我们可以将Context类改造成简单工厂。这样,客户端不必选择好策略传递给Context,只需要传递表示当前情况的字段,让Context类根据获取到的不同情况,选择合适的策略。
在这个例子里,我们可以理解为:在早餐店,客户只需要喊一声:我要吃...,老板会帮你拿的。
话不多说,让我们将前面的代码稍作调整。
首先是环境类Context:
//环境类
class Context {
public static final String DUMPLINGS = "蒸饺";
public static final String STEAMED_BUN = "红糖馒头";
private Strategy strategy;
public void startStrategy(String type) {
System.out.println("客官稍等,我马上拿给您");
switch (type) {
//执行策略A
case DUMPLINGS:
strategy = new ConcreteStrategyA();
break;
//执行策略B
case STEAMED_BUN:
strategy = new ConcreteStrategyB();
break;
default:
break;
}
strategy.strategyMethod();
}
}
然后是客户端:
package Strategy;
import static Strategy.Context.DUMPLINGS;
import static Strategy.Context.STEAMED_BUN;
//策略工厂模式
public class StrategyPattern {
public static void main(String[] args) {
Context c = new Context();
//想吃饺子
System.out.println("我想吃"+ DUMPLINGS);
c.startStrategy(DUMPLINGS);
System.out.println("-----------------");
//想吃红糖馒头
System.out.println("我想吃"+ STEAMED_BUN);
c.startStrategy(STEAMED_BUN);
}
}
程序运行结果
我想吃蒸饺
客官稍等,我马上拿给您
执行策略A:从蒸笼里拿一份蒸饺
-----------------
我想吃红糖馒头
客官稍等,我马上拿给您
执行策略B:从蒸笼里拿一个红糖馒头
好了,关于策略模式的初步理解,就到这里了。本人也是刚接触设计模式,想分享下自己的理解与大家互相提高。文中若有不恰当的地方,有劳各位指出,多谢观看!