一、策略模式的概念
策略模式定义
定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。
使用的场景
- 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
- 一个系统需要动态地在几种算法中选择一种。
- 如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
角色介绍
策略模式通用UML
-
Strategy抽象策略角色
策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。
-
ConcreteStrategy具体策略角色
实现抽象策略中的操作,该类含有具体的算法。
-
Context封装角色
它也叫做上下文角色,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。
二、案列实现
小Y最近在玩比较有情怀的经典游戏魂斗罗.归来,看着熟悉的场景,心里感慨万分,以前只是想着怎么样才能开挂式地打爆机,现在玩起来更多的是回味经典和享受运用不同的策略闯过不同的关卡的快感。小Y在选择角色的时候最喜欢使用比尔·雷泽这个口叼雪茄的粗狂肌肉男,同时不同的对战模式采取不同的武器。
不同对战模式采取不同武器装备
tell me why?
Ok,please keep looking!
1.不同对战模式采取不同武器的UML图
①武器切换接口
public interface IWeaponStrategy {
public void operate();
}
②1vs1对战模式
public class OnetoOneFight implements IWeaponStrategy {
public void operate() {
System.out.println("狙击枪+喷射器:1vs1关键就是能够快速的对对方造成大量的伤害,狙击枪和喷射器都是高伤害的武器。");
}
}
③3vs3对战模式
public class ThreetoThreeFight implements IWeaponStrategy {
public void operate() {
System.out.println("炮类+突击步枪:3vs3需要有着高伤害的范围攻击,从而压制对手占领据点,炮类伤害大,突击步枪也能弥补炮类换弹速度慢的劣势。");
}
}
④关卡对战模式
public class BarrierFight implements IWeaponStrategy {
public void operate() {
System.out.println("机关枪+突击步枪:关卡模式中,小兵比较多,但是时常也得面对BOSS的突袭,因此选择能力较为均衡的武器是比较好的选择。");
}
}
⑤对战模式
public class Context {
//构造函数,你要使用玩那种模式
private IWeaponStrategy straegy;
public Context(IWeaponStrategy strategy){
this.straegy = strategy;
}
//根据不同模式装备不同武器
public void operate(){
this.straegy.operate();
}
}
⑥使用不同武器
public class BillRizer {
//比尔.雷泽出场了,他根据不同模式选择了不同的武器
public static void main(String[] args) {
Context context;
//1vs1对战
context = new Context(new OnetoOneFight());
context.operate();
//3vs3对战模式
context = new Context(new ThreetoThreeFight());
context.operate();
//关卡对战模式
context = new Context(new BarrierFight());
context.operate();
}
}
输出的结果为:
①狙击枪+喷射器:1vs1关键就是能够快速的对对方造成大量的伤害,狙击枪和喷射器都是高伤害的武器。
②炮类+突击步枪:3vs3需要有着高伤害的范围攻击,从而压制对手占领据点,炮类伤害大,突击步枪也能弥补炮类换弹速度慢的劣势。
③机关枪+突击步枪:关卡模式中,小兵比较多,但是时常也得面对BOSS的突袭,因此选择能力较为均衡的武器是比较好的选择。
小Y还要继续努力,争取能够早日打爆机。。。。
三、总结分析
-
策略模式就是这么简单,它就是采用了面向对象的继承和多态机制。
-
优点:
①算法可以自由切换,通过封装角色对其进行封装,保证对外提供“可自由切换”的策略。
②避免使用多重条件判断。
③扩展性良好,增加一个策略只需要实现一个接口就可以了。 -
缺点:
①策略类数量增多,策略类数量增多,每一个策略都是一个类,复用的可能性很小,类数量增多。
②所有的策略类都需要对外暴露,上层模块必须知道有哪些策略,然后才能决定使用哪一个策略,这与迪米特法则是相违背的,可以使用工厂方法模式、代理模式修整这个缺陷。