Android设计模式之策略模式
2016-12-30 09:59
507 查看
非常感谢:http://blog.csdn.net/lmj623565791/article/details/24116745博主的分享,也是本文主要学习来源。
下面就用实例讲解策略模式,大家应该都玩过角色游戏,下面我就以角色游戏为背景,为大家介绍:假设公司需要做一款武侠游戏,我们就是负责游戏的角色模块,需求是这样的:每个角色对应一个名字,每类角色对应一种样子,每个角色拥有一个逃跑、攻击、防御的技能。
版本1.0
没几分钟,你写好了上面的代码,觉得已经充分发挥了OO的思想,正在窃喜,这时候项目经理说,再添加两个角色:
RoleB(样子2 ,降龙十八掌,铁布衫,金蝉脱壳)。
RoleC(样子1,拥有九阳神功,铁布衫,烟雾弹)。
于是你觉得没问题,开始写代码,继续集成Role,写成下面的代码:
写完之后,你自己似乎没有当初那么自信了,你发现代码中已经存在相当多重复的代码,需要考虑重新设计架构了。于是你想,要不把每个技能都写成接口,有什么技能的角色实现什么接口,简单一想,觉得这想法高大尚啊,但是实现起来会发现,接口并不能实现代码的复用,每个实现接口的类,还是必须写自己写实现。于是,we need change ! 遵循设计的原则,找出应用中可能需要变化的部分,把它们独立出来,不要和那些不需要变化的代码混在一起。我们发现,对于每个角色的dis
4000
play,attack,defend,run都是有可能变化的,于是我们必须把这写独立出来。再根据另一个设计原则:针对接口(超类型)编程,而不是针对实现编程,于是我们把代码改造成这样:
版本2.0
这时候需要对Role的代码做出改变:
每个角色现在只需要一个name了:
现在我们需要一个金蝉脱壳,降龙十八掌!,铁布衫,样子1的角色A只需要这样:
经过我们的修改,现在所有的技能的实现做到了100%的复用,并且随便项目经理需要什么样的角色,对于我们来说只需要动态设置一下技能和展示方式,是不是很完美。恭喜你,现在你已经学会了策略模式,现在我们回到定义,定义上的算法族:其实就是上述例子的技能;定义上的客户:其实就是RoleA,RoleB…;我们已经定义了一个算法族(各种技能),且根据需求可以进行相互替换,算法(各种技能)的实现独立于客户(角色)。现在是不是很好理解策略模式的定义了。
附上一张UML图,方便大家理解:
最后总结一下OO的原则:
1、封装变化(把可能变化的代码封装起来)
2、多用组合,少用继承(我们使用组合的方式,为客户设置了算法)
3、针对接口编程,不针对实现(对于Role类的设计完全的针对角色,和技能的实现没有关系)
完整的代码下载
概念解析
策略模式(Strategy Pattern):定义了算法族,分别封装起来,让它们之间可相互替换,此模式让算法的变化独立于使用算法的客户。下面就用实例讲解策略模式,大家应该都玩过角色游戏,下面我就以角色游戏为背景,为大家介绍:假设公司需要做一款武侠游戏,我们就是负责游戏的角色模块,需求是这样的:每个角色对应一个名字,每类角色对应一种样子,每个角色拥有一个逃跑、攻击、防御的技能。
版本1.0
package com.cc.csdndemo; /** * 游戏的角色超类 * * @author cc * */ 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.cc.csdndemo; public class RoleA extends Role { public RoleA(String name) { this.name = name; } @Override protected void display() { Log.d("TAG","样子1"); } @Override protected void run() { Log.d("TAG","金蝉脱壳"); } @Override protected void attack() { Log.d("TAG","降龙十八掌"); } @Override protected void defend() { Log.d("TAG","铁头功"); } }
没几分钟,你写好了上面的代码,觉得已经充分发挥了OO的思想,正在窃喜,这时候项目经理说,再添加两个角色:
RoleB(样子2 ,降龙十八掌,铁布衫,金蝉脱壳)。
RoleC(样子1,拥有九阳神功,铁布衫,烟雾弹)。
于是你觉得没问题,开始写代码,继续集成Role,写成下面的代码:
package com.cc.csdndemo; public class RoleB extends Role { public RoleB(String name) { this.name = name; } @Override protected void display() { Log.d("TAG","样子2"); } @Override protected void run() { Log.d("TAG","金蝉脱壳"); } @Override protected void attack() { Log.d("TAG","降龙十八掌"); } @Override protected void defend() { Log.d("TAG","铁布衫"); } }
package com.cc.csdndemo; public class RoleC extends Role { public RoleC(String name) { this.name = name; } @Override protected void display() { Log.d("TAG","样子1"); } @Override protected void run() { Log.d("TAG","烟雾弹"); } @Override protected void attack() { Log.d("TAG","九阳神功"); } @Override protected void defend() { Log.d("TAG","铁布衫"); } }
写完之后,你自己似乎没有当初那么自信了,你发现代码中已经存在相当多重复的代码,需要考虑重新设计架构了。于是你想,要不把每个技能都写成接口,有什么技能的角色实现什么接口,简单一想,觉得这想法高大尚啊,但是实现起来会发现,接口并不能实现代码的复用,每个实现接口的类,还是必须写自己写实现。于是,we need change ! 遵循设计的原则,找出应用中可能需要变化的部分,把它们独立出来,不要和那些不需要变化的代码混在一起。我们发现,对于每个角色的dis
4000
play,attack,defend,run都是有可能变化的,于是我们必须把这写独立出来。再根据另一个设计原则:针对接口(超类型)编程,而不是针对实现编程,于是我们把代码改造成这样:
版本2.0
package com.cc.csdndemo; public interface IAttackBehavior { void attack(); }
package com.cc.csdndemo; public interface IDefendBehavior { void defend(); }
package com.cc.csdndemo; public interface IDisplayBehavior { void display(); }
package com.cc.csdndemo; public interface IRunBehavior { void run(); }
package com.cc.csdndemo; public class AttackJY implements IAttackBehavior { @Override public void attack() { Log.d("TAG","九阳神功!"); } }
package com.cc.csdndemo; public class DefendTBS implements IDefendBehavior { @Override public void defend() { Log.d("TAG","铁布衫"); } }
package com.cc.csdndemo; public class RunJCTQ implements IRunBehavior { @Override public void run() { Log.d("TAG","金蝉脱壳"); } }
这时候需要对Role的代码做出改变:
package com.cc.csdndemo; /** * 游戏的角色超类 * * @author cc * */ 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.cc.csdndemo; public class RoleA extends Role { public RoleA(String name) { this.name = name; } }
现在我们需要一个金蝉脱壳,降龙十八掌!,铁布衫,样子1的角色A只需要这样:
package com.cc.csdndemo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Role roleA = new RoleA("A"); roleA.setAttackBehavior(new AttackJY()) .setDefendBehavior(new DefendTBS()) .setDisplayBehavior(new DisplayA()) .setRunBehavior(new RunJCTQ()); Log.d("TAG", roleA.name + ":"); roleA.run(); roleA.attack(); roleA.defend(); roleA.display(); } }
经过我们的修改,现在所有的技能的实现做到了100%的复用,并且随便项目经理需要什么样的角色,对于我们来说只需要动态设置一下技能和展示方式,是不是很完美。恭喜你,现在你已经学会了策略模式,现在我们回到定义,定义上的算法族:其实就是上述例子的技能;定义上的客户:其实就是RoleA,RoleB…;我们已经定义了一个算法族(各种技能),且根据需求可以进行相互替换,算法(各种技能)的实现独立于客户(角色)。现在是不是很好理解策略模式的定义了。
附上一张UML图,方便大家理解:
最后总结一下OO的原则:
1、封装变化(把可能变化的代码封装起来)
2、多用组合,少用继承(我们使用组合的方式,为客户设置了算法)
3、针对接口编程,不针对实现(对于Role类的设计完全的针对角色,和技能的实现没有关系)
完整的代码下载
相关文章推荐
- android应用开发设计模式之策略模式
- Android和设计模式:策略模式
- android设计模式之策略模式
- Android设计模式—策略模式
- 浅学设计模式之策略<Strategy>模式及在android中的使用
- android设计模式-策略模式
- Android设计模式—策略模式
- Android设计模式系列—策略模式
- Android 设计模式之策略模式
- Android设计模式系列—策略模式
- Android 设计模式:(一)策略模式 —— 封装行为的大局观
- Android设计模式系列—策略模式
- Android 设计模式:(一)策略模式 —— 封装行为的大局观
- Android[高级教程] 设计模式之二 策略模式
- Android 设计模式:(一)策略模式 —— 封装行为的大局观
- Android使用的设计模式2——策略模式
- Android使用的设计模式2——策略模式
- Android设计模式(二)--策略模式
- Android中设计模式--策略模式(封装会变化的算法部分,面向接口不针对实现)
- 浅学设计模式之策略<Strategy>模式及在android中的使用