一.策略模式
将每一种算法都封装到具有共同接口的独立的类中,是算法本身和使用算法的对象分离开来,解决了多种相似算法情况下,以往if...else编程带来的复杂和难以维护。
1.封装变化。
2.使用接口编程。
该模式中包含的角色及其职责:
1.抽象策略角色:具体策略角色的抽象父类。
2.具体策略角色:包装了具体的算法和行为。
3.环境角色:内部会持有一个抽象角色的引用,给客户端调用。
优点:
1.减少了算法类和使用算法类之间的耦合。(扩展性好)
2.Strategy类的层次为Context定义了一系列可供重用的算法或功能,有助于析出这些算法的共有功能,比如可以把实现同一场景的算法的结果可以析出抽象的结果对象。(抽象复用)
3.简化单元测试,每个算法都有自己的类,可以通过自己的接口单独测试。
4.当不同的行为出现堆砌在同一类中,就难免使用条件判断选择合适的行为,将算法封装在不同的行为类里,消除了条件语句。(避免多重条件判断)
5.策略模式不光可以封装算法,当不同场景需要用不同的业务规则解决时,都可以考虑业务类。它将选择具体实现的职责由客户端转向类策略模式的Context对象。
缺点:
1.策略类会增多。
2.所有策略类都需要对外暴露。
例子:诸葛亮为孙刘联军出的计谋为抽象策略角色,具体的计谋为具体策略角色,战役为环境角色,赤壁之战就是这次具体的战役。
抽象策略角色(诸葛亮的n个计谋):
package strategy;
/**
* 抽象策略角色 诸葛亮的计谋s
* @author liucong8
*/
public interface Strategy {
/**
* 实现两军可以打仗的方法
* @param sunLiu 孙刘联军
* @param caoCao 曹操大军
* @return 战役结果
*/
public String fighting(String sunLiu, String caoCao);
}
具体策略角色(诸葛亮n个计谋的具体实现):
计谋一:水攻
package strategy;
/**
* 策略一:诸葛亮出了水攻的计谋
* @author liucong8
*/
public class WaterStrategy implements Strategy {
@Override
public String fighting(String sunLiu, String caoCao) {
System.out.println("孙刘联军用水对曹操大军进行攻击。");
return "曹操大军玩耍的很开心,孙刘很崩溃。";
}
}
计谋二:火攻
package strategy;
/**
* 策略二:诸葛亮出了火攻的计谋
* @author liucong8
*/
public class FireStrategy implements Strategy {
@Override
public String fighting(String sunLiu, String caoCao) {
System.out.println("孙刘联军用火对曹操大军进行攻击。");
return "火烧赤壁,曹操大败。";
}
}
计谋三:使用网络喷子
package strategy;
/**
* 策略三:诸葛亮出了调用喷子的计谋
* @author liucong8
*/
public class ScoldStrategy implements Strategy {
@Override
public String fighting(String sunLiu, String caoCao) {
System.out.println("孙刘联军使用互联网喷子对曹操大军进行攻击。");
return "两家互喷,不相上下。";
}
}
环境角色(具体的战役场景是哪里呢?赤壁?官渡?汉中?):
package strategy;
import com.sun.org.apache.regexp.internal.RE;
/**
* 到底使用哪种计谋呢?
* @author liucong8
*/
public class Environment {
/**
* 持有对策略类的引用,即计谋列表
*/
private Strategy strategy;
public Environment(Strategy strategy) {
this.strategy = strategy;
}
/**
* 赤壁之战
* @param sunLiu 孙刘联军
* @param caoCao 曹操大军
* @return 结果
*/
public String chiBiWar(String sunLiu, String caoCao) {
return strategy.fighting(sunLiu, caoCao);
}
}
测试客户端(赤壁之战开打!):
package strategy;
/**
* 测试客户端 赤壁开打ing
* @author liucong8
*/
public class StrategyTest {
public static final String SUNLIU = "孙刘联军";
public static final String CAOCAO = "曹操大军";
public static void main(String[] args) {
/**
* 传入具体的策略类(决定啦!!!使用火攻!)
*/
Environment environment = new Environment(new FireStrategy());
String result = environment.chiBiWar(SUNLIU, CAOCAO);
/**
* 赤壁之战的结果
*/
System.out.println(result);
}
}
结果:
任何需求变更都需要成本,如何用最小的成本达到最大的效果就是高手和初学者的区别。