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

设计模式之策略模式

时间:2015-12-02 16:12:33      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:

  The Game Awards 2015主持人Geoff Keighley宣布将把今年的行业标志将(Industry Icon Award)颁给传奇工作室Westwood Studios的两位创始人。

  想起了2004年跟室友玩红警,那哥们造了满屏的坦克,浩浩荡荡的来推我的基地。坦克太多,多到我们那赛扬的机器卡地不要不要的。

  忽然好怀念那段时光,也不知道远在武汉的兄弟,现在如何。

  今天开始学习设计模式,就以红色警戒为例吧,也顺便缅怀一下大学时光。

 


  今天讲的是策略模式,先不讲定义,先看场景。

   游戏中会造很多大兵,每个大兵都有基本的走路、巡逻的功能。为了复用代码,我建立了一个父类,所有的兵种都继承自这个父类。

技术分享

  那么问题来了,游戏运行起来,你会发现美国大兵、伞兵、解放军、尤里的攻击方式都一样。怎么办呢,有两个办法。

  1.在美国大兵、伞兵、解放军、尤里中覆盖父类的方法,这样攻击起来都使用各自的方法了,但是你发现其实美国大兵和伞兵的攻击方式其实是一样的,所以代码需要写两遍。

  2.把Soldier声明成接口,每个子类实现接口的方法。但是所有的兵种都有冲锋的功能,所有具体实现类都得不厌其烦的ctrl-C ctrl-V  rush的方法。一旦领导说开个加速,所有的兵rush的速度快一点, 。。。我得加班改所有子类的rush方法。

  我们可以看到,在父类中有的方法是变化的,有的是不变的,那就引出了我们的第一条设计原则:

 

找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。

 怎么独立呢,首先想到的是把攻击变成一个接口类,所有兵种都实现这个接口,那么就变成这样:

技术分享

  好啦,还是那个问题,美国大兵和伞兵攻击的方式其实是一样的,还是得ctrl-c ctrl-v。而且攻击方式变的话,俩都得改。而且万一大兵升级成了三等兵,攻击速度快了,或者攻击方式变了怎么办呢?接下来我们看第二个设计原则。

针对接口编程,而不是针对实现编程。

   我们利用接口代表每个行为,比如说fireable,行为的每个实现代表一种行为方式。各个兵种只需要包含一个行为方式的对象而不用实现这个接口。

  技术分享

  普通箭头是“有一个”的关系,带三角的箭头是“是一个”的关系。有一个就是组合(Composition)。这种做法和“继承”不同的地方在于,开火的行为不是继承来的,而是和适当的行为对象“组合”来的。

多用组合,少用继承

   现在可以说说策略模式的定义了:

 

策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

 

 java实现如下:

Fireable行为接口

package com.zzl.designpattern.strategy;

public interface IFireable {
    public void fire();
}

 

 

FireWithGun类

package com.zzl.designpattern.strategy;

public class FireWithGun implements IFireable {

    @Override
    public void fire() {
        System.out.println("使用左轮枪攻击");
    }
}

FireWithAK47类

package com.zzl.designpattern.strategy;

public class FireWithAK47 implements IFireable {

    @Override
    public void fire() {
        System.out.println("使用AK47攻击!");
    }
}

 

 Solider大兵抽象类

技术分享
package com.zzl.designpattern.strategy;

public abstract class Solider {
    /**
    * 行为类
    */
    IFireable fireable;

    /**
    * 冲刺
    */
    public void rush(String direction){
        System.out.println("向 " + direction + " 冲刺");

    }
    /**
    * 升级
    */
    public abstract void  partrol();
    /**
    * 开火
    */
    public void fire(){
        fireable.fire();
    }
    /**
    * setFireable
    */
    public void setFireable(IFireable fireable){
        this.fireable = fireable;
    }
}
View Code

 

FootSolider美国大兵类

技术分享
package com.zzl.designpattern.strategy;

public class FootSolider extends Solider {

    public FootSolider(){
        fireable = new FireWithGun();
        System.out.println("新建一个一级美国大兵");
    }

    @Override
    public void partrol() {
        System.out.println("美国大兵升级了!");
        this.setFireable(new FireWithAK47());
    }
}
View Code

 

Game游戏类

技术分享
package com.zzl.designpattern.strategy;

public class Game {

    public static void main(String[] args) {
        Solider footSolider = new FootSolider();
        footSolider.rush("左");
        footSolider.fire();
        footSolider.partrol();
        footSolider.fire();
    }

}
View Code

 

运行结果

技术分享
新建一个一级美国大兵
向 左 冲刺
使用左轮枪攻击
美国大兵升级了!
使用AK47攻击!
Console

 

设计模式之策略模式

标签:

原文地址:http://www.cnblogs.com/liangflying521/p/5012755.html

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