zoukankan      html  css  js  c++  java
  • 简单设计模式——状态模式 (召唤师峡谷版)

    召唤师峡谷中的各位英雄在进入召唤师峡谷的时候,都需要遵循召唤师峡谷的宇宙定律。每位英雄在战斗中是有不同的状态的。刚开始每个人都是正常状态,这时候移动、攻击、释放技能没有任何限制。但是当一个英雄被虚弱了,他的移速就变慢了,攻击伤害也降低;当影响被沉默,他就无法释放技能;等等等。
    这里面的每个不同状态都对应着一个英雄的一个不同的行为。

    简介

    状态模式(Sate Pattern):当一个对象的状态改变的时候,他的行为也相应的改变。即行为是根据状态改变的。

    状态模式中使用的类

    1. Context:一个含有不同状态的对象。比如:如果程序是上面的召唤师峡谷,那么这个对象就是操作的游戏角色。
    2. State:状态接口(也可以是抽象类)。规定了状态的方法(行为)集合。
    3. State的实现类:上面的State的具体实现类。一般情况下,Context有多少个状态,就有多少个State实现类。因为每种状态下的实现是不一样的。

    实例

    我们就用开头提到的召唤师峡谷的例子来做一个例子。
    现在要求实现一个操作英雄的功能,在英雄不同状态下。用户的操作会有不同的反应。这时候要怎么设计呢?

    分析

    首先我们想到的就是操作的角色是一个对象,而他又有不同的状态。这不是就是状态模式可以嘛?好巧。
    我们要操作的游戏角色有很多不同的状态,对应的就是状态模式的Context,叫Context不好听,我们就叫他PlayerContext(好像也不好听,其实没必要加Context,但是为了清晰的看清这个对象在状态模式中是哪部分,还是这样取)。
    不管在什么状态下我们都会需要一个方法,那就是英雄的行为:所以我们在接口State中就需要有个action方法。
    英雄有几个状态,我们就申明几个实例:SilenceState(沉默状态)、WeakState(虚弱状态)、CommonState(正常状态)。

    代码实现

    1. 声明State接口。
    public interface State {
        //状态的行为
        void action();
    }
    
    1. 实现沉默状态下的行为:SilenceState
    //沉默状态
    public class SilenceState implements State {
        @Override
        public void action() {
            System.out.println("沉默状态=>无法释放技能");
        }
    }
    
    1. 实现沉虚弱态下的行为:WeakState
    public class WeakState  implements State {
        @Override
        public void action() {
            System.out.println("削弱状态=>角色移动缓慢,攻击伤害低");
        }
    }
    
    1. 实现沉虚弱态下的行为:CommonState
    public class CommonState implements State {
        @Override
        public void action() {
            System.out.println("正常状态=>移动正常、攻速正常、技能正常");
        }
    }
    
    1. 各个状态下英雄的行为已经写好了,下面我们来实现英雄类:PlayerContext
    public class PlayerContext {
        //使用组合的方法,将各种状态注入的游戏角色对象中。
        private State state;
        
        public PlayerContext(){
            //实例化游戏角色的时候给一个,默认状态
            state=new CommonState();
        }
        //设置角色的状态
        public void setState(State state){
            this.state=state;
        }
        
        //角色被操作。
        public void operate(){
            //实际上调用的是注入的那个状态对象的行为方法,而不是角色本身的方法。
            state.action();
        }
    }
    
    1. 来测试一下
    public class Test {
        public static void main(String[] args) {
            PlayerContext playerContext=new PlayerContext();
            //模拟用户操作
            playerContext.operate();
            System.out.println("================");
    
            //模拟游戏角色被沉默了
            playerContext.setState(new SilenceState());
            //模拟用户操作
            playerContext.operate();
            System.out.println("================");
    
            //模拟游戏角色被虚弱了
            playerContext.setState(new WeakState());
            //模拟用户操作
            playerContext.operate();
            System.out.println("================");
        }
    }
    
    1. 输出结果
    正常状态=>移动正常、攻速正常、技能正常
    ================
    沉默状态=>无法释放技能
    ================
    削弱状态=>角色移动缓慢,攻击伤害低
    ================
    

    其他

    还有很多好玩的例子可以自己动手实现一下,其实设计模式有时候理解起来不难,难得是在合适的时候使用合适的设计模式。
    比如:人是不是有不同的状态(生病:咳嗽;劳累:想睡觉;饥饿:想吃饭;)、我们购物的时候一个商品是不是也有不同的状态(被加入购物车;被收藏;下单;付款)等等。

    作者:BobC

    文章原创。如你发现错误,欢迎指正,在这里先谢过了。博主的所有的文章、笔记都会在优化并整理后发布在个人公众号上,如果我的笔记对你有一定的用处的话,欢迎关注一下,我会提供更多优质的笔记的。
  • 相关阅读:
    特NB的本地语音识别方案(转)
    海思MPP(转)
    单片机实现PT2262解码示例代码(转)
    海思HI35XX之----视频处理单元各通道间的关系(转)
    海思AI芯片(Hi3519A/3559A)方案学习(三)Ubuntu18.0.4上编译Hi3519AV100 uboot和kernel(转)
    Hi3519V101开发环境搭建(二)(转)
    Git 原理
    海思3531添加移远EC20 4g模块(转)
    将移远通信的EC20驱动移植到NUC972上(转)
    Shell 正则表达式
  • 原文地址:https://www.cnblogs.com/Eastry/p/12713289.html
Copyright © 2011-2022 走看看