简单设计模式——状态模式 (召唤师峡谷版)
召唤师峡谷中的各位英雄在进入召唤师峡谷的时候,都需要遵循召唤师峡谷的宇宙定律。每位英雄在战斗中是有不同的状态的。刚开始每个人都是正常状态,这时候移动、攻击、释放技能没有任何限制。但是当一个英雄被虚弱了,他的移速就变慢了,攻击伤害也降低;当影响被沉默,他就无法释放技能;等等等。
这里面的每个不同状态都对应着一个英雄的一个不同的行为。
简介
状态模式(Sate Pattern):当一个对象的状态改变的时候,他的行为也相应的改变。即行为是根据状态改变的。
状态模式中使用的类
- Context:一个含有不同状态的对象。比如:如果程序是上面的召唤师峡谷,那么这个对象就是操作的游戏角色。
- State:状态接口(也可以是抽象类)。规定了状态的方法(行为)集合。
- State的实现类:上面的State的具体实现类。一般情况下,Context有多少个状态,就有多少个State实现类。因为每种状态下的实现是不一样的。
实例
我们就用开头提到的召唤师峡谷的例子来做一个例子。
现在要求实现一个操作英雄的功能,在英雄不同状态下。用户的操作会有不同的反应。这时候要怎么设计呢?
分析
首先我们想到的就是操作的角色是一个对象,而他又有不同的状态。这不是就是状态模式可以嘛?好巧。
我们要操作的游戏角色有很多不同的状态,对应的就是状态模式的Context,叫Context不好听,我们就叫他PlayerContext(好像也不好听,其实没必要加Context,但是为了清晰的看清这个对象在状态模式中是哪部分,还是这样取)。
不管在什么状态下我们都会需要一个方法,那就是英雄的行为:所以我们在接口State中就需要有个action方法。
英雄有几个状态,我们就申明几个实例:SilenceState(沉默状态)、WeakState(虚弱状态)、CommonState(正常状态)。
代码实现
- 声明State接口。
public interface State {
//状态的行为
void action();
}
- 实现沉默状态下的行为:SilenceState
//沉默状态
public class SilenceState implements State {
@Override
public void action() {
System.out.println("沉默状态=>无法释放技能");
}
}
- 实现沉虚弱态下的行为:WeakState
public class WeakState implements State {
@Override
public void action() {
System.out.println("削弱状态=>角色移动缓慢,攻击伤害低");
}
}
- 实现沉虚弱态下的行为:CommonState
public class CommonState implements State {
@Override
public void action() {
System.out.println("正常状态=>移动正常、攻速正常、技能正常");
}
}
- 各个状态下英雄的行为已经写好了,下面我们来实现英雄类: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();
}
}
- 来测试一下
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("================");
}
}
- 输出结果
正常状态=>移动正常、攻速正常、技能正常
================
沉默状态=>无法释放技能
================
削弱状态=>角色移动缓慢,攻击伤害低
================
其他
还有很多好玩的例子可以自己动手实现一下,其实设计模式有时候理解起来不难,难得是在合适的时候使用合适的设计模式。
比如:人是不是有不同的状态(生病:咳嗽;劳累:想睡觉;饥饿:想吃饭;)、我们购物的时候一个商品是不是也有不同的状态(被加入购物车;被收藏;下单;付款)等等。
作者:BobC
文章原创。如你发现错误,欢迎指正,在这里先谢过了。博主的所有的文章、笔记都会在优化并整理后发布在个人公众号上,如果我的笔记对你有一定的用处的话,欢迎关注一下,我会提供更多优质的笔记的。