什么是策略模式
将一组算法,封装到具有共同接口的独立类中,这些类可以相互转化。
结构类图
策略模式【Strategy】
- 【抽象策略】Strategy : 通常由接口/抽象类实现,给出具体的策略所需要的方法。
- 【具体策略】ConcreteStrategy : 具体实现的策略算法和步骤。
- 【封装类】Context : 持有一个Strategy的引用。对策略二次封装,避免了对策略的直接使用。
举栗时间
话说诸葛亮上知天文下知地理,用兵如神,尤其是用火能力,火烧博望坡,火烧赤壁。下面列出使用比较频繁的几个兵法
- 烈火术
- 八卦阵法
- 草船借箭
- 空城计
抽象策略
public interface IStrategy {//给出策略所需的接口
void warMethod();
}
具体策略
public class FireStrategy implements IStrategy {//具体实现的策略
@Override
public void warMethod() {
System.out.println("【烈火术】谁烧山谁坐牢,牢底坐穿");
}
}
public class BaGuaStrategy implements IStrategy {//具体实现的策略
@Override
public void warMethod() {
System.out.println("【八卦阵】变化万端,可当十万精兵");
}
}
public class CaoChuanStrategy implements IStrategy {//具体实现的策略
@Override
public void warMethod() {
System.out.println("【草船借箭】用的是疑兵计");
}
}
public class EmptyCityStrategy implements IStrategy {//具体实现的策略
@Override
public void warMethod() {
System.out.println("【空城计】这城市那么空,这记忆那么凶");
}
}
封装类
这个将军持有策略的引用,即诸葛亮给他什么策略,他都可以使用,而不影响其他功能,经过将军的二次加工,使策略表现的更有力。【这个将军应该是姜维】
public class General {
private IStrategy mStrategy;
public General(IStrategy strategy) {
this.mStrategy = strategy;
}
public void Yell(){
System.out.println("将军:【众将听令,摆列阵法】");
mStrategy.warMethod();
}
}
实战结果
我们来看一下这位将军的吸收和领悟能力,诸葛亮一口气new了4个兵法丢给这位将军。
General general;
general = new General(new FireStrategy());
general.Yell();
System.out.println("\n------------------------------------\n");
general = new General(new BaGuaStrategy());
general.Yell();
System.out.println("\n------------------------------------\n");
general = new General(new CaoChuanStrategy());
general.Yell();
System.out.println("\n------------------------------------\n");
general = new General(new EmptyCityStrategy());
general.Yell();
System.out.println("\n------------------------------------");
总结
策略模板优点
- 各种策略【兵法】之前切换自如,不同的策略能够发挥不同作用。比较容易在原有代码上进行扩展。
- 避免使用多重判断,多重判断比较难维护。
策略模板缺点
- 如果策略类多就难维护了,而且你还必须得了解那种场景使用那种策略【兵法】。