策略模式,定义了一系列算法,并将它们封装,使它们之间可以相互替换,无论使用哪种算法或者策略,最终都会达到调用者的目的,策略模式侧重如何组织这些算法,而不是侧重如何实现某种算法。
策略模式,通过对算法封装,将算法的责任和实现分开,并委派给不同的对象对这些算法进行管理。
策略模式有以下特点:
- 可以避免使用多重条件语句
- 对同一行为提供了不同的实现,调用者可以根据自身的时间或者空间要求,选择不同的算法。
- 策略模式很好支持开闭原则,在不用修改源代码的情况下,灵活新增算法。
以实际生活中的例子,我们旅行时乘坐交通工具为例,从北京到武汉,飞机和火车是两种不同的交通工具,他们的体验和性价比是不一样的,飞机能够快速到达目的地,但是价格昂贵,适合商务出行。火车速度远不及飞机,即使是高铁,从北京到武汉也需要5~6个小时,绿皮火车可能需要12个小时或者更久,价格也便宜,这种适合时间充裕,不慌不忙的旅行出行。他们虽然各方面有差异,但是都能到达目的地。乘客只需要根据自己的时间和空间来决定需要乘坐哪种交通工具。
策略模式使用的前提是,调用者需要清楚有哪些策略可供选择以及他们的区别。
策略模式的哲学思想:条条大路通罗马,殊途共归,求同存异。
下面以交通工具为例,展示策略模式的例子:
Transport.java
package com.xxx.design.strategy;
public interface Transport {
double run(double km);
}
Plane.java
package com.xxx.design.strategy;
public class Plane implements Transport {
@Override
public double run(double km) {
//speed 800km/h
System.out.println("飞机飞行时速800km/h");
return km/800;
}
}
Train.java
package com.xxx.design.strategy;
public class Train implements Transport {
@Override
public double run(double km) {
//绿皮火车速度是80km/h
System.out.println("绿皮火车时速80km/h");
return km/80;
}
}
TransportSpeedTest.java
package com.xxx.design.strategy;
public class TransportSpeedTest {
public static void main(String[] args) {
double length = 1200d;
Transport plane = new Plane();
double time = plane.run(length);
System.out.printf("air travel takes %s hours.",time);
System.out.println();
Transport train = new Train();
time = train.run(length);
System.out.printf("train travel takes %s hours.",time);
System.out.println();
}
}
运行TransportSpeedTest类主方法,打印结果如下:
飞机飞行时速800km/h
air travel takes 1.5 hours.
绿皮火车时速80km/h
train travel takes 15.0 hours.
至此,策略模式介绍完了,策略模式要求算法的实现独立出来,便于管理,如果算法实现办法很多,那么会造成很多的策略类,这也算是策略模式的一个缺点了。