《魂斗罗归来》之状态模式VS策略模式

欢迎收看俗到掉渣的《小Y讲堂》节目,大家好,我是小Y,一个集性感毛发与才华于一身的程序猿。小Y的设计模式系列中的「状态模式」「策略模式」都已经总结完成了,很多小伙伴都会凌乱在这两种模式当中,小Y曾经也被凌乱到无法自拔。。。

一、模式对战前的准备

两个类图都非常相似,都是通过Context类封装了一个具体的行为,都提供了一个封装方法,是高扩展性的设计模式。它们就像一对孪生兄弟一样,通过通用UML根本没有办法区分出不同之处。小Y举个例子来区分它们之间的不同点。

小Y玩《魂斗罗归来》有自己的一套方法和习惯,每次都会按照先闯关卡对战☞1vs1对战模式☞3vs3对战模式的顺序来进行游戏冲关(突然感觉小Y的强迫症在加重...)。1vs1、3vs3、关卡对战至关重要的一点就是要选择武器,1vs1模式选择的武器就是狙击枪+喷射器,3vs3模式选择的武器是炮类+突击步枪,关卡对战选择的武器是机关枪+突击步枪。按照策略模式来分析,根据三种对战模式选择武器就是三个不同的具体算法,算法之间没有交互,以达到算法可以自由切换,随着不同的对战模式而进行武器的更换;按照状态模式来分析,小Y的打游戏的顺序(关卡对战☞1vs1对战模式☞3vs3对战模式)就被看做三个不同的状态,每个状态的改变,就会引起行为的变化,同时每个状态的变化都会指定下一个状态。

二、策略模式实现武器切换

1.策略模式武器切换类图

2.切换的代码清单

①武器切换抽象类

public abstract class ISwitch {  
    public abstract void switch();
}  

②关卡对战模式

public class BarrierFight extends ISwitch {  
    public void switch() {  
        System.out.println("BillRizer选择的武器:机关枪+突击步枪"); 
    }
}

③1vs1对战模式

public class OnetoOneFight extends ISwitch {  
    public void switch() {  
        System.out.println("BillRizer选择的武器:狙击枪+喷射器"); 
    }
}   

④3vs3对战模式

public class ThreetoThreeFight extends ISwitch {  
    public void switch() {  
        System.out.println("BillRizer选择的武器:炮类+突击步枪"); 
    }
}

⑤对战模式

public class Context {    
    //构造函数,要使用玩哪种模式  
    private ISwitch switchStrategy;  
    public Context(ISwitch switchStrategy){  
        this.SwitchStrategy = switchStrategy;
    }
    //根据不同模式选择不同武器
    public void switch(){  
        this.switchStrategy.switch();  
    }  
}

⑥使用不同武器

public class xiaoY {   
    //小Y开始打游戏了,根据不同模式选择了不同的武器  
    public static void main(String[] args) {  
        Context context;  
        //关卡对战模式  
        context = new Context(new BarrierFight());  
        context.switch();
        //1vs1对战
        context = new Context(new OnetoOneFight());
        context.switch(); 
        //3vs3对战模式    
        context = new Context(new ThreetoThreeFight());  
        context.switch();   
     
    }  
}

输出的结果为:

①BillRizer选择的武器:机关枪+突击步枪
②BillRizer选择的武器:狙击枪+喷射器
③BillRizer选择的武器:炮类+突击步枪

三、状态模式实现武器切换

1.状态模式武器切换类图

2.切换的代码清单

①武器切换抽象类

public abstract class ISwitch {  
    protected Context context;
    public void setContext(Context context){
        this.context=context;
    }
    public abstract void switch();
}  

②关卡对战模式

public class BarrierFight extends ISwitch {  
    public void switch() {  
        System.out.println("BillRizer选择的武器:机关枪+突击步枪"); 
        super.context.setState(ONE_FIGHT_STATE);
    }
}

③1vs1对战模式

public class OnetoOneFight extends ISwitch {  
    public void switch() {  
        System.out.println("BillRizer选择的武器:狙击枪+喷射器"); 
        super.context.setState(THREE_FIGHT_STATE);
    }
}   

④3vs3对战模式

public class ThreetoThreeFight extends ISwitch {  
    public void switch() {  
        System.out.println("BillRizer选择的武器:炮类+突击步枪"); 
    }
}

⑤对战模式

public class Context {
    //定义对战的几种模式    
    public static final ISwitch BARRIER_FIGHT_STATE=new BarrierFight();
    public static final ISwitch ONE_FIGHT_STATE=new OnetoOneFight();
    public static final ISwitch THREE_FIGHT_STATE=new ThreetoThreeFight();
    private ISwitch switchState;  

    public void setState(ISwitch switchState){  
        this.switchState = switchState;
        this.switchState.setContext(this);
    }
    //根据不同模式选择不同武器
    public void switch(){  
        this.switchState.switch();  
    }  
}

⑥使用不同武器

public class BillRizer {   
    //比尔.雷泽出场了,他根据不同模式选择了不同的武器  
    public static void main(String[] args) {  
        Context context;  
        context = new Context(); 
        //关卡对战模式  
        context.setState(new BarrierFight()); 
        context.switch();
        //1vs1对战
        context.switch();
        //3vs3对战模式    
        context.switch();
     
    }  
}

输出的结果为:

①BillRizer选择的武器:机关枪+突击步枪
②BillRizer选择的武器:狙击枪+喷射器
③BillRizer选择的武器:炮类+突击步枪

两种模式运行的结果都是相同的,但是两者的分析角度是大相径庭的,实现通过采用策略模式实现了“切换武器”这个策略的三种不同算法,算法可以自由切换,到底用哪个算法由调用者决定,因此策略模式的使用重点是算法的自由切换,增加新的算法对整体功能没有非常大的改变,非常灵活;而状态模式是从小Y打游戏闯关的顺序来分析,每个关卡代表的状态对应了不同的行为,状态改变后行为也随之改变,每个状态的变化都会指定下一个状态。

三、小结

从以上示例中我们也可以看出,对于相同的业务需求,有很多种实现方法,问题的重点是业务关注的是什么,只有找准了业务的焦点,才能够选择更加合适的设计模式。

虽然我们从通用UML图上称他们为亲兄弟,但是从上面的两个代码清单可以看出这两者还是存在着非常大的差别,很容易区分出来。

  • 策略模式算法可以自由切换,到底用哪个算法由调用者决定;状态模式是初始化一个状态,之后的每个状态的变化都会指定下一个状态。

  • 环境角色的职责不同。两者都有一个叫做Context环境角色的类,但是两者的区别很大,策略模式的环境角色只是一个委托作用,负责算法的替换;而状态模式的环境角色不仅仅是委托行为,它还具有登记状态变化的功能,与具体的状态类协作,共同完成状态切换行为随之切换的任务。

  • 应用场景不同。,策略模式只是一个算法的封装,可以是一个有意义的对象,也可以是一个无意义的逻辑片段;状态模式则要求有一系列状态发生变化的场景,它要求的是有状态且有行为的场景

  • 解决问题的方法不同。策略模式只是确保算法可以自由切换,但是什么时候用什么算法它决定不了;状态模式对外暴露的是行为,状态的变化一般是由环境角色和具体状态共同完成的。

掘金地址:https://juejin.im/post/59fc3b9151882574d172498e

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

推荐阅读更多精彩内容