策略模式简单谈

面向对象的编程不可避免的需要使用到各种各样的设计模式,设计模式可以使得代码更优雅,变得更加有弹性,设计模式带来的好处不需要再多说了,作者原先写的是Lua代码,函数式编程语言,没有很强的面向对象,因此很少会使用到设计模式。

最近开始接触Java的游戏服务端,发现里面的代码虽然看得懂,但是总是很难理解,不知道其为什么这样设计,后面慢慢发现里面运用到了很多设计模式,为了更好的理解代码,作者开始学习设计模式,在此记文。

首先接触到的是策略模式,我会用自己的理解来写一个简单的例子,就不说很多理论了。我发现大学时读过的设计模式,那个时候觉得应用性不足,因为看了觉得很有道理,但是很难联想其应用场景,老是会有疑问,这个到底用在哪里。但是当做过的项目多了之后,这些疑问就会得到解决,因为在做项目过程中你会遇到很多问题,然后你会发现恰当的设计模式能很好的解决你这个问题,这个时候你才会觉得前人总结的设计模式的伟大之处。

那么什么是策略模式呢?

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

这是非常官方的描述,单独看这个描述肯定一头雾水,当然我不打算去解释这个定义,我只是简单谈一下我对策略模式的运用,至于完不完全符合策略模式就看实际情况的运用了,理论只是起指导作用,我觉得不可生搬硬套。

当我们需要设计一个类的时候,我们总是需要去思考这个类哪些属性是不需要改变的,哪些属性是需要动态变化的,不需要改变的通常是对象共有的属性,需要变化的则是对象的个性化,这在生活中很常见,我们总是拥有某些共性的同时,保留自己的个性。

让我们假设一个场景,游戏中玩家需要战斗,战斗需要武器,每个玩家是一个个体,你会很容易发现这里的共性是玩家的基本属性,如姓名、年龄等,行为共性则是战斗,玩家都需要战斗,但是战斗使用的武器是不一样的,每个玩家的都不一样,同一个玩家也可能换武器,因此设计的时候不能把武器的实现与玩家绑死。

下面是设计的类图:


类图.png

实现代码例子为:

//Character.java
package com.base;

//玩家战斗不变的基础属性独立出来的超类,可复用
public class Character {
    //玩家的共有的属性
    private String name;
    private int age;
    
    //Weapon是一个接口
    protected Weapon w;
    
    public String getName(){
        return name;
    }
    
    public void setName(String name){
        this.name = name;
    }
    
    public int getAge(){
        return age;
    }
    
    public void setAge(int age){
        this.age = age;
    }
    
    //可以动态的改变武器
    public void setWeapon(Weapon wt){
        this.w = wt;
    }
    
    //玩家都是使用武器战斗,但不同玩家拥有不同的武器
    public void fight(){
        w.useWeaponFight();
    }
    
}

Character是一个超类,通过继承Character实现每个玩家类,你会发现Character的变量成员和方法都没有被绑死,拿fight()方法来谈,不管w接口由谁实现,反正这里调用的就是useWeaponFight()方法,使用武器进行战斗,战斗是每个玩家都必须具备的,这个在这个场景下永远不会改变,同时还提供:

setWeapon(Weapon wt) 

方法,可以动态改变武器,玩家也不会和武器类绑死,这样设计类代码可以具备足够的弹性。

下面其它类的简单实现:

//Weapon.java
package com.base;

//武器接口,通过实现该接口产生不同的武器
public interface Weapon {
    public void useWeaponFight();
}

//StrongWeapon.java
package player;
import com.base.Weapon;

//实现一个强力武器
public class StrongWeapon implements Weapon{
    public void useWeaponFight(){
        System.out.println("Use Strong Power Weapon Fighting!");
    }
}

//StrongPlayer.java
package player;
import com.base.Character;
//产生一个玩家,玩家的武器初始化在构造器中
public class StrongPlayer extends Character{
    public StrongPlayer(){
        this.w = new StrongWeapon();
    }
}
//WeakWeapon.java
package player;
import com.base.Weapon;

//实现一个弱势武器
public class WeakWeapon implements Weapon{
    public void useWeaponFight() {
        System.out.println("Use Weak Weapon Fighting!");
    }
}

//WeakPlayer,java
package player;
import com.base.Character;

public class WeakPlayer extends Character{

    public WeakPlayer() {
        this.w = new WeakWeapon();
    }
}

然后我们来测试一下两个玩家类,测试代码为:

//StartFight.java
import player.*;

public class StartFight {
    public static void main(String[] args){
        StrongPlayer sp = new StrongPlayer();
        sp.fight();
        
        WeakPlayer wp = new WeakPlayer();
        wp.fight();
        
        //切换武器
        sp.setWeapon(new WeakWeapon());
        sp.fight();
        
        //切换强力的武器
        wp.setWeapon(new StrongWeapon());
        wp.fight();
    }
}

输出结果:

Use Strong Power Weapon Fighting!
Use Weak Weapon Fighting!
Use Weak Weapon Fighting!
Use Strong Power Weapon Fighting!

上面只是一个简单的例子,回到策略模式的定义,这里所谓的封装的算法族体现为每个武器类,每个武器类的使用武器的方法useWeaponFight()都是不一样的,这个算法是可以变化的,比如StrongWeapon,假设现在需求改变了该武器的使用方法,那么我们只需要修改StrongWeapon的useWeaponFight()方法就可以了,原来的代码都不用修改,这样就达到了我们设计良好代码的目的啦。

以上为策略模式简单谈的全部内容,接下来会继续学习其他设计模式,也会继续和大家分享,该案例的工程代码也上传至github,有兴趣的同学可以继续扩展。https://github.com/huchangwei/StrategyMode

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容