本文参考:
https://www.cnblogs.com/jenkinschan/p/5645300.html
https://www.cnblogs.com/fengyumeng/p/10842631.html
一、策略模式定义
我们知道一件事可能会有很多种方式来实现它,但是其中总有一种最高效的方式,在软件开发的世界里面同样如此,我们也有很多中方法来实现一个功能,但是我们需要一种简单、高效的方式来实现它,使得系统能够非常灵活,这就是策略模式。
定义算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。这算法体现了几个设计原则:
第一、把变化的代码从不变的代码中分离出来;
第二、针对接口编程而不是具体类(定义了策略接口);
第三、多用组合,少用继承(客户通过组合方式使用策略)。
二、策略模式类图
策略模式包含如下角色:
Context: 环境类
Strategy: 抽象策略类
ConcreteStrategy: 具体策略类
三、应用实例
以华山论剑为例,要知道每个剑侠都有一把属于自己的好剑,不论什么剑都有自己的优点和缺点,打比赛需要讲究策略,随机应变,变换招式等等。
------欧阳锋对郭靖------
带上小李飞刀!
------欧阳锋对洪七公------
带上倚天剑!
------欧阳锋对杨过------
带上屠龙刀!
武器抽象:
public interface IWeapon {
void exec();//每把武器都可以佩戴
}
屠龙刀:
public class TuLongDao implements IWeapon {
@Override
public void exec() {
System.out.println("带上屠龙刀!");
}
}
倚天剑:
public class YiTianJian implements IWeapon {
@Override
public void exec() {
System.out.println("带上倚天剑!");
}
}
小李飞刀:
public class XiaoLiFeiDao implements IWeapon {
@Override
public void exec() {
System.out.println("带上小李飞刀!");
}
}
上下文对象,负责维护对武器的引用:
public class Context {
private IWeapon weapon;
//传入一把武器
public Context(IWeapon weapon) {
this.weapon = weapon;
}
//佩戴武器,分分钟秒杀你
public void exec(){
this.weapon.exec();
}
}
测试:
public static void main(String[] args) {
System.out.println("华山论剑开始:");
System.out.println("------欧阳锋对郭靖------");
Context context1 = new Context(new XiaoLiFeiDao());
context1.exec();
System.out.println("------欧阳锋对洪七公------");
Context context2 = new Context(new Yitian());
context2.exec();
System.out.println("------欧阳锋对杨过------");
Context context3 = new Context(new TuLong());
context3.exec();
}
华山论剑开始:
------欧阳锋对郭靖------
带上小李飞刀!
------欧阳锋对洪七公------
带上倚天剑!
------欧阳锋对杨过------
带上屠龙刀!
四.优点和不足
1.优点
(1).体现了“对修改关闭,对扩展开放”原则,客户端增加行为不用修改原有代码,只要添加一种策略即可。
(2).避免了使用多重转移语句(if..else if..else)。
(3).提供了可以替换继承关系的办法: 继承提供了另一种支持多种算法或行为的方法。你可以直接生成一个Context类的子类,从而给它以不同的行为。但这会将行为硬行编制到 Context中,而将算法的实现与Context的实现混合起来,从而使Context难以理解、难以维护和难以扩展,而且还不能动态地改变算法。最后你得到一堆相关的类 , 它们之间的唯一差别是它们所使用的算法或行为。 将算法封装在独立的Strategy类中使得你可以独立于其Context改变它,使它易于切换、易于理解、易于扩展。
2.缺点
(1).每添加一个策略就要增加一个类,当策略过多是会导致类数目庞大。
(2).客户端需明确知道系统有哪些策略可以使用,当策略过多时客户端的学习成本较高。
五.使用场景
1.如果一个系统里有很多类,他们只是某个行为不同时,使用策略模式可以让一个对象在许多行为中选择一种行为。
2.一个系统需要动态地在几种算法中选择一种。
3.有多重转移条件语句考虑使用策略模式。