策略模式
欧阳锋买剑
大家好,我是小赵,现任藏剑山庄高级铸剑师。
我铸的剑质量都属上层,无论是玄铁重剑、屠龙刀、紫薇软剑、三叉戟等等,只要江湖上排的上号的我几乎都能做的出来,所以在圈内还算是小有名气。
今天朋友给我介绍了个私活,雇主是欧阳锋,据说是想打造一把神兵利器。
“锋哥,讲一下你的需求吧。”
“华山论剑在即,我要当天下第一!”。
“.......”
我感觉这位峰哥是不是有点不正常,那干脆我来引导一下需求吧,于是我问道:“峰哥是不是想要一把绝世好剑?”
“不错,小伙子很懂我!就要一把绝世好剑!”
锋哥的绝世好剑
几天之后,我打造出了这把绝世好剑:
public class JueShi { public void exec(){ System.out.println("装备绝世好剑!"); } }
使用简单,只需要调一下exec()方法就佩戴上了:
public static void main(String[] args) { System.out.println("----- 欧阳锋 -----"); JueShi jueShi = new JueShi(); jueShi.exec(); }
输出:
----- 欧阳锋 -----
装备绝世好剑!
峰哥高高兴兴拿着绝世好剑回去。
三天后,气呼呼来找我了。
“小赵!我这把绝世好剑,我拿去跟聂风打,跟岳不群打,都打赢了,怎么跟我干儿子打就打不赢!?”
“你干儿子?哪位啊?”
“杨过啊!”
我草,杨过用的是玄铁重剑,这把绝世好剑肯定打不过人家,那可怎么办?那能怎么办?天下武器环环相克,不可能一把武器无敌天下。
华山论剑
我心生一计,立刻说道:“峰哥,你看要不这样,你多打造几把神兵利器,实战中根据对手的不同而更换不同的武器,保准打遍天下无敌手。”
“好主意!我现在最忌惮的人就郭靖、洪七公、杨过三个人,郭靖用掌、洪七公用棍、杨过用剑,你只要保证我把这三个打败就行了。”
生意谈好之后,就开始设计开发了。
我的策略很简单:
郭靖用掌,怕远程,那就用小李飞刀对付他。
洪七公用棍,选用倚天剑即可,削铁如泥又不失灵活。
杨过的玄铁重剑?一把屠龙刀砍翻他!
角色1:武器(小李飞刀、倚天剑、屠龙刀都是武器),也就是武器抽象和武器实体。
角色2:峰哥,我们这里重点探讨策略,所以峰哥就不存在了,当成主函数即可。
动作:更换武器(也就是接收一个武器,并且佩戴)。
类图非常的简单:
几天后,峰哥来取剑。
武器抽象:
public interface IWeapon { void exec();//每把武器都可以佩戴 }
屠龙刀:
public class TuLong implements IWeapon{ @Override public void exec() { System.out.println("带上屠龙刀!"); } }
倚天剑:
public class Yitian 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(); }
输出:
华山论剑开始:
------欧阳锋对郭靖------
带上小李飞刀!
------欧阳锋对洪七公------
带上倚天剑!
------欧阳锋对杨过------
带上屠龙刀!
华山论剑是二十年一度的江湖奥运会,各个电视台都在同步直播,在直播里,我看到了峰哥意气风发,遇神杀神,遇佛杀佛,最终获得了天下第一的称号。
策略模式
给峰哥设计的这套程序,使用了策略模式,这是一个相对于比较简单的设计模式。
策略模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
策略模式的三个角色:
Context封装角色,也叫做上下文角色,起到封装作用,屏蔽高层模块对策略的直接访问。
策略抽象角色,让每个策略实现的接口。
具体策略角色,实现抽象策略接口,并实现具体的算法内容。
策略模式的优点在于策略可以自由切换,并且扩展性很好,如果要增加一个新策略,只需要实现策略抽象接口即可。
当一个业务需要多种算法自由切换的时候,并且希望屏蔽算法的具体内容,只需要调用一下即获取结果,则优先考虑策略模式。