该系列文章为博主学习笔记,原文请参考参考链接
本文禁止转载,但是欢迎大家留言区留言交流[微笑]
策略类简单的来说就是将某一种算法封装成为一个类,将算法的行为和环境分离出来。
举个例子,现在将一个班的学习成绩进行等级划分,90分以上的是A类,70-90是B类,剩下的为C类。
public class Score {
public void category(int s) {
if (s > 90) {
System.out.println("A");
} else if (s > 70 && s < 90) {
System.out.println("B");
} else {
System.out.println("C");
}
}
}
public class myClass {
public static void main(String[] args) {
Score score=new Score();
score.category(60);
}
}
这种代码方式在之前开发中经常出现,但是从今天起,学完策略模式,就要避免这种写法了。
算法的行为:根据不同的分值进行不同的处理
环境:Score类
如果以后项目扩展增加了更多的算法,首先会使Score类的代码量变大。其次,Score类封装了不同的算法,违法了类的单一设计模式。再其次,如果要增加、删除、修改该类的算法,违反了开闭原则。
所以要将环境和算法的行为进行分离,就引入了策略模式进行解决。
UML:
从图中可以看到Context为环境类,并且关联抽象策略类,在程序运行的过程中指定具体的策略类。
Strategy为抽象策略类,所有的具体策略类(ConcreteStrategyA)都应该实现该抽象策略类。
下面以具体代码为例:
这里可以把每一种飞机的种类看成具体策略类,因为不同的飞机种类,他们的起飞特征和飞行特征都大不相同。
代码:
public abstract class AbstractPlane {
public abstract void PlaneType();
public abstract void StartFlyType();
public abstract void FlyingType();
}
public class AirPlane extends AbstractPlane {
@Override
public void PlaneType() {
System.out.println("客机");
}
@Override
public void StartFlyType() {
System.out.println("长距离起飞");
}
@Override
public void FlyingType() {
System.out.println("亚音速飞行");
}
}
public class Fighterplane extends AbstractPlane {
@Override
public void PlaneType() {
System.out.println("歼击机");
}
@Override
public void StartFlyType() {
System.out.println("长距离起飞");
}
@Override
public void FlyingType() {
System.out.println("超音速飞行");
}
}
public class HelicopterPlane extends AbstractPlane{
@Override
public void PlaneType() {
System.out.println("直升机");
}
@Override
public void StartFlyType() {
System.out.println("垂直起飞");
}
@Override
public void FlyingType() {
System.out.println("亚音速飞行");
}
}
public class Context {
private AbstractPlane abstractPlane;
public void setAbstractPlane(AbstractPlane abstractPlane) {
this.abstractPlane = abstractPlane;
}
public void PlanePrint() {
abstractPlane.PlaneType();
abstractPlane.StartFlyType();
abstractPlane.FlyingType();
}
}
public class myClass {
public static void main(String[] args) {
Context context = new Context();
AbstractPlane strategy;
strategy = new Fighterplane(); //可在运行时指定类型
context.setAbstractPlane(strategy);
context.PlanePrint();
}
}
输出:
歼击机
长距离起飞
超音速飞行
但是策略模式也存在很多的缺点:如果存在多个具体策略类,这无疑会使类的数量增多,客户端需要了解每一种算法,来选择不同的具体策略类。无法同时在客户端使用多个策略类,也就是说,在使用策略模式时,客户端每次只能使用一个策略类,不支持使用一个策略类完成部分功能后再使用另一个策略类来完成剩余功能的情况。
微信公众号:
QQ群:365473065