简单设计模式——状态模式 (召唤师峡谷版)

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

简介

状态模式(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

文章原创。如你发现错误,欢迎指正,在这里先谢过了。博主的所有的文章、笔记都会在优化并整理后发布在个人公众号上,如果我的笔记对你有一定的用处的话,欢迎关注一下,我会提供更多优质的笔记的。
原文地址:https://www.cnblogs.com/Eastry/p/12713289.html