策略模式包含如下角色:
Context: 环境类
Strategy: 抽象策略类
ConcreteStrategy: 具体策略类
我们知道一件事可能会有很多种方式来实现它,但是其中总有一种最高效的方式,在软件开发的世界里面同样如此,我们也有很多中方法来实现一个功能,但是我们需要一种简单、高效的方式来实现它,使得系统能够非常灵活,这就是策略模式。
所以策略模式就是定义了算法族,分别封装起来,让他们之前可以互相转换,此模式然该算法的变化独立于使用算法的客户。
在策略模式中它将这些解决问题的方法定义成一个算法群,每一个方法都对应着一个具体的算法,这里的一个算法我就称之为一个策略。虽然策略模式定义了算法,但是它并不提供算法的选择,即什么算法对于什么问题最合适这是策略模式所不关心的,所以对于策略的选择还是要客户端来做。客户必须要清楚的知道每个算法之间的区别和在什么时候什么地方使用什么策略是最合适的,这样就增加客户端的负担。
同时策略模式也非常完美的符合了“开闭原则”,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。但是一个策略对应一个类将会是系统产生很多的策略类。
demo
package strategy_method_mod;
import org.junit.Test;
/**
* 策略模式
* 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
*
* 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
*
* 介绍
* 意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
*
* 主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
*
* 何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
*
* 如何解决:将这些算法封装成一个一个的类,任意地替换。
*
* 关键代码:实现同一个接口。
*
* 应用实例: 1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。 2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。 3、JAVA AWT 中的 LayoutManager。
*
* 优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
*
* 缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。
*
* 使用场景: 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中选择一种。 3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
*
* 注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。
*/
public class Client {
@Test
public void test(){
Context context = new Context(new BusTraffic());
context.excuteStrategy("小明");
System.out.println("-------不同的人选择不同的出行模式----------");
Context context1 = new Context(new PlaneTraffic());
context1.excuteStrategy("小刘");
}
}
抽象策略类
package strategy_method_mod;
/**
* Strategy: 抽象策略类
*/
public interface Traffic {
public void getTraffic(String name);
}
具体策略类 巴士
package strategy_method_mod;
/**
* ConcreteStrategy: 具体策略类
*/
public class BusTraffic implements Traffic {
@Override
public void getTraffic(String name) {
System.out.println(String.format("%s选择乘坐大巴出行",name));
}
}
具体策略类 飞机
package strategy_method_mod;
/**
* ConcreteStrategy: 具体策略类
*/
public class PlaneTraffic implements Traffic {
@Override
public void getTraffic(String name) {
System.out.println(String.format("%s选择乘坐飞机出行",name));
}
}
环境类,管理策略
package strategy_method_mod;
/**
* Context: 环境类
*/
public class Context {
private Traffic traffic;
public Context(Traffic traffic){
this.traffic = traffic;
}
public void excuteStrategy (String name){
traffic.getTraffic(name);
}
}