话不多说,先盗个图
怎么解释这个策略模式呢?
首先 定义一个接口Strategy 之后用具体实现类实现StrategyImpl 再然后定义一个Context类持有接口Strategy 之后就可以 在客户端用这个context了
有什么好处呢?算法分离的好处 解耦
ok上代码:
public interface UserStategy { public void changeInfo(String name,String image); }
public class PersonUserStategy implements UserStategy { public void changeInfo(String name, String image) { System.out.println("PersonUserStategy+"+name+"+"+image); } }
public class VIPSUerStategy implements UserStategy{ public void changeInfo(String name, String image) { System.out.println("VIPSUerStategy+"+name+"+"+image); } }
public class Context { private UserStategy userStategy; private String age; private String home; public Context(UserStategy userStategy) { this.userStategy = userStategy; } public void doChangeUserInfo(String name, String image){ userStategy.changeInfo(name,image); } }
public class RunMain { public static void main(String[] args){ UserStategy userStategy=new VIPSUerStategy(); Context context=new Context(userStategy); context.doChangeUserInfo("小红红","小马相片"); } }
输出结果
VIPSUerStategy+小红红+小马相片
如此就完成了算法的分离 普通用户和vip用户的算法是不一样的~
策略模式没什么值得推敲的地方,唯有这个Context类 为什么会必须存在一个Context类持有Strategy变量呢 我直接使用strategy对象不行吗? 不能达到一样的效果吗? 我把代码改成这个样子:
public class RunMain { public static void main(String[] args){ UserStategy userStategy=new VIPSUerStategy(); userStategy.changeInfo("小红红","小马相片"); } }
这样不是一样能算法分离吗? 为什么一定要有一个Context类持有Stategy呢?
关于这个问题网上的说法不一,找了很多博客依然无法说服我自己,我依然是感觉不必须的,也是策略模式最核心的东西吧~
网上的说法:它可以解耦,比较容易调用....
直到我看了一本书《大话设计模式》中的例子,才感觉到 这个类存在的的原因
下面修改一下以上代码 : UserStategy,PersonUserStategy,VIPUSerStategy均无变化 RunMain和Context变化成:
public class Context { private UserStategy userStategy; public Context(int type) { switch (type){ case 0: userStategy=new PersonUserStategy(); break; case 1: userStategy=new VIPSUerStategy(); break; } } public void doChangeUserInfo(String name, String image){ userStategy.changeInfo(name,image); } }
public class RunMain { public static void main(String[] args){ int type=0; Context context=new Context(type); context.doChangeUserInfo("小红红","小马相片"); } }
这样根据type值就可以直接切换算法~ 这样客户端调用的更加简单,Context类在策略模式中被称为上下文环境,在这个例子中完美的诠释了这个名字,承上启下~ 承接客户端的调用,开启算法的调用
如此客户端只是调用算法,对算法具体什么样子,怎么执行完全无感
如此Context承接上下文,负责 调用哪个算法,用什么变量 对算法具体执行什么样子完全无感,对谁调用了自己也完全没有感觉
如此Stategy 专注于算法,对于谁调用了自己,完全无感。
这样满足 单一职责原则,完全解耦~ 把这一个大的事情拆分为3个小的执行模块 --客户端,Context,Stategy。 客户端只关心调用,最多关心一下Context ,不关心算法内部, Context承接客户端调用和Stategy Stategy只关心算法的执行~~~
可以理解Context类是把客户端调用适配到Stategy算法的一个中间层的类,没有这个类,很多工作就会分到客户端 这样客户端代码就不优雅了~ 写出来的东西就很凌乱了。。。。