码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式之-策略模式

时间:2015-06-07 23:39:53      阅读:261      评论:0      收藏:0      [点我收藏+]

标签:设计模式

问题描述

实现游戏的不同角色

某游戏中Queen,King,Knight这3种角色,每种角色都有使用武器行为,设计这三个类,提高代码的重用性和可维护性。

解决方案

Queen,King,Knight这三个角色都是角色,都可以move,可以stop,因此可以设计一个Character抽象类,抽取三个角色的共同行为,减少代码的重复性,Character定义如下:

public abstract class Character {
     public void move() { // do move action }
     public void stop() { // do stop action }
     public void useWeapon() { // do use sword}
}

三个角色继承于Character这个抽象类, 但是如果Queen用的武器是枪呢? 可以在子类重写该方法啊!

public class Queen() extends Character { 
    @Override
    public void useWeapon() {
        // do use gun 
    }
}
public class King() extends Character { ... }
public class Knight() extends Character { ... }

但是还有一个问题,如果我新增了其他角色,当然继承于Character,如果新增的这个类没有使用武器的行为呢?
还有另外一种解决方法,将容易改变的行为抽象成一个接口。

public abstract class Character {
     public void move() { // do move action }
     public void stop() { // do stop action }
}

public interface WeaponBehavior {
    void useWeapon();
} 

public class King extends Character implements WeaponBehavior   {
    public void useWeapon() { // do use sword }
} 

public class Queen extends Character implements WeaponBehavior   {
    public void useWeapon() { // do use sword }
} 

public class Knight implements WeaponBehavior extends Character  {
    public void useWeapon() { // do use gun }
} 

上面接口的方式看上去挺合理的,但是角色一多就会发现在useWeapon方法中会出现大量的代码重复,虽然可以将重复代码抽取出来放到其他地方,但是这样就破坏了类的封装性。

存在问题

  • 用继承的方法会让代码不灵活,不支持子类中没有该方法的行为,如果修改了父类的方法会让所有类都产生影响
  • 使用接口的方法增加了重复代码
  • 上面两种方法还有一个缺点,对象的行为在编译时候已经确定,无法在运行时候更改
  • 如果对象的使用武器行为有所改变,改其中的代码将是一件非常痛苦的事情

策略模式

考虑到不同对象使用不同的武器,而且使用武器方法会不断改变,最好将经常改变的东西封装起来,以后一旦有需要修改的,则只需要修改封装部分就可以,而其他模块不会受到影响。策略模式的核心思想就是把变化的行为(算法)封装,让他们可以相互替换,这个模式可以让变化的算法独立于使用这些行为(算法)的客户。具体看下面的实现:

public interface WeaponBehavior {
    void useWeapon();
}

public class SwordBehavior implements WeaponBehavior {
    @Override
    public void useWeapon() { // do sword behavior }
}

public class GunBehavior implements WeaponBehavior {
    @Override
    public void useWeapon() { // do gun behavior }
}

public abstract class Character {
     WeaponBehavior weaponBehavior;
     public void move() { // do move action }
     public void stop() { // do stop action }
     public void useWeapon() {
         weaponBehavior.useWeapon();
     }
        public setWeaponBehavior(WeaponBehavior weaponBehavior) {
        this.weaponBehavior = weaponBehavior;
    }
}

public class King extends Character {
    public King() {
        weaponBehavior = new GunBehavior();
    }
}

public class Queen extends Character {
    public Queen() {
        weaponBehavior = new SwordBehavior();
    }
}

如上代码所示,将经常需要改变的行为封装成类,有如下好处:

  1. 当需求变动时,只需修改封装的类,对于客户端代码可以保持原样,系统更具有弹性
  2. 当程序运行时候,可以调用setter来改变对象的行为
  3. 当新增一些其他行为的时候,不会影响到原有的对象的行为

总结

策略模式适用于有多类似对象,这些对象又有类似行为,并且行为会不断发生变化这样的场景。策略模式将算法封装起来,让算法之间可以相互替换,并且这种替换对使用算法的客户来说是独立的。
策略模式体现了软件设计的原则:

  1. 找出应用中可能变化的地方,把他们独立出来,不要和那些需求不变的代码混在一起
  2. 要针对接口编程,不要对实现编程
  3. 多用组合,少用继承 : 在系统中使用组合可以让系统有更大的弹性,不仅可以应对算法的变化,更可以在运行时动态改变行为

设计模式之-策略模式

标签:设计模式

原文地址:http://blog.csdn.net/jackie_zhu/article/details/46404599

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!