策略模式
来源:互联网 发布:炒股模拟软件 知乎 编辑:程序博客网 时间:2024/06/05 04:24
先来看看策略模式的定义:
策略模式(Strategy Pattern):定义了算法族,分别封装起来,让它们之间可相互替换,此模式让算法的变化独立于使用算法的客户。
大家应该都玩过武侠角色游戏,下面我就以角色游戏为背景,为大家介绍:假设公司需要做一款武侠游戏,我们负责游戏的角色模块,需求是这样的:每个角色对应一个名字,每类角色对应一种样子,每个角色拥有一个逃跑、攻击、防御的技能。
初步的代码:
- package com.zhy.bean;
- /**
- * 游戏的角色超类
- *
- * @author zhy
- *
- */
- public abstract class Role
- {
- protected String name;
- protected abstract void display();
- protected abstract void run();
- protected abstract void attack();
- protected abstract void defend();
- }
- package com.zhy.bean;
- public class RoleA extends Role
- {
- public RoleA(String name)
- {
- this.name = name;
- }
- @Override
- protected void display()
- {
- System.out.println("样子1");
- }
- @Override
- protected void run()
- {
- System.out.println("金蝉脱壳");
- }
- @Override
- protected void attack()
- {
- System.out.println("降龙十八掌");
- }
- @Override
- protected void defend()
- {
- System.out.println("铁头功");
- }
- }
没几分钟,你写好了上面的代码,觉得已经充分发挥了OO的思想,正在窃喜,这时候项目经理说,再添加两个角色
RoleB(样子2 ,降龙十八掌,铁布衫,金蝉脱壳)。
RoleC(样子1,拥有九阳神功,铁布衫,烟雾弹)。
于是你觉得没问题,开始写代码,继续集成Role,写成下面的代码:
- package com.zhy.bean;
- public class RoleB extends Role
- {
- public RoleB(String name)
- {
- this.name = name;
- }
- @Override
- protected void display()
- {
- System.out.println("样子2");
- }
- @Override
- protected void run()
- {
- System.out.println("金蝉脱壳");//从RoleA中拷贝
- }
- @Override
- protected void attack()
- {
- System.out.println("降龙十八掌");//从RoleA中拷贝
- }
- @Override
- protected void defend()
- {
- System.out.println("铁布衫");
- }
- }
- package com.zhy.bean;
- public class RoleC extends Role
- {
- public RoleC(String name)
- {
- this.name = name;
- }
- @Override
- protected void display()
- {
- System.out.println("样子1");//从RoleA中拷贝
- }
- @Override
- protected void run()
- {
- System.out.println("烟雾弹");
- }
- @Override
- protected void attack()
- {
- System.out.println("九阳神功");
- }
- @Override
- protected void defend()
- {
- System.out.println("铁布衫");//从B中拷贝
- }
- package com.zhy.bean;
- public interface IAttackBehavior
- {
- void attack();
- }
- package com.zhy.bean;
- public interface IDefendBehavior
- {
- void defend();
- }
- package com.zhy.bean;
- public interface IDisplayBehavior
- {
- void display();
- }
- package com.zhy.bean;
- public class AttackJY implements IAttackBehavior
- {
- @Override
- public void attack()
- {
- System.out.println("九阳神功!");
- }
- }
- package com.zhy.bean;
- public class DefendTBS implements IDefendBehavior
- {
- @Override
- public void defend()
- {
- System.out.println("铁布衫");
- }
- }
- package com.zhy.bean;
- public class RunJCTQ implements IRunBehavior
- {
- @Override
- public void run()
- {
- System.out.println("金蝉脱壳");
- }
- }
这时候需要对Role的代码做出改变:
- package com.zhy.bean;
- /**
- * 游戏的角色超类
- *
- * @author zhy
- *
- */
- public abstract class Role
- {
- protected String name;
- protected IDefendBehavior defendBehavior;
- protected IDisplayBehavior displayBehavior;
- protected IRunBehavior runBehavior;
- protected IAttackBehavior attackBehavior;
- public Role setDefendBehavior(IDefendBehavior defendBehavior)
- {
- this.defendBehavior = defendBehavior;
- return this;
- }
- public Role setDisplayBehavior(IDisplayBehavior displayBehavior)
- {
- this.displayBehavior = displayBehavior;
- return this;
- }
- public Role setRunBehavior(IRunBehavior runBehavior)
- {
- this.runBehavior = runBehavior;
- return this;
- }
- public Role setAttackBehavior(IAttackBehavior attackBehavior)
- {
- this.attackBehavior = attackBehavior;
- return this;
- }
- protected void display()
- {
- displayBehavior.display();
- }
- protected void run()
- {
- runBehavior.run();
- }
- protected void attack()
- {
- attackBehavior.attack();
- }
- protected void defend()
- {
- defendBehavior.defend();
- }
- }
每个角色现在只需要一个name了:
- package com.zhy.bean;
- public class RoleA extends Role
- {
- public RoleA(String name)
- {
- this.name = name;
- }
- }
现在我们需要一个金蝉脱壳,降龙十八掌!,铁布衫,样子1的角色A只需要这样:
- package com.zhy.bean;
- public class Test
- {
- public static void main(String[] args)
- {
- Role roleA = new RoleA("A");
- roleA.setAttackBehavior(new AttackXL())//
- .setDefendBehavior(new DefendTBS())//
- .setDisplayBehavior(new DisplayA())//
- .setRunBehavior(new RunJCTQ());
- System.out.println(roleA.name + ":");
- roleA.run();
- roleA.attack();
- roleA.defend();
- roleA.display();
- }
- }
经过我们的修改,现在所有的技能的实现做到了100%的复用,并且随便项目经理需要什么样的角色,对于我们来说只需要动态设置一下技能和展示方式,是不是很完美。恭喜你,现在你已经学会了策略模式,现在我们回到定义,定义上的算法族:其实就是上述例子的技能;定义上的客户:其实就是RoleA,RoleB...;我们已经定义了一个算法族(各种技能),且根据需求可以进行相互替换,算法(各种技能)的实现独立于客户(角色)。
附上一张UML图,方便大家理解:
最后总结一下OO的原则:
1、封装变化(把可能变化的代码封装起来)
2、多用组合,少用继承(我们使用组合的方式,为客户设置了算法)
3、针对接口编程,不针对实现(对于Role类的设计完全的针对角色,和技能的实现没有关系)
0 0
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 三次握手的第三个ACK包丢了——客户端认为连接建立,写数据时,会触发RST
- Eclipse快捷键 10个最有用的快捷键
- xhprof安装&&使用
- Java中的方法重载(method overloading)和方法重写(method Overriding)的区别
- Oracle11g客户端的安装及配置
- 策略模式
- Android开发错误处理
- 实现AJAX的基本步骤
- 给在读研究生+未来要读研同学们的一封受益匪浅的信
- [leetcode] Combination Sum II
- JAVA文件访问控制
- SD/MMC/SDIO 概要
- Response.WriteFile 无法下载大文件解决方法
- Android SDK更新以及ADT更新出现问题的解决办法