如果我们正在做一个实时战略游戏。我们设计了一个武器,他制作只是当步兵,但他能够切换武器。第一个开关会变成弓箭手,第二个开关导通控股装甲盾牌,第三开关变成步兵……如何实现这一目标切换机构?我们开始思考,增加步兵在这个类switch声明。话,代码不利于扩展,不利于改动,这时我们就能够使用状态模式了。
状态模式同意一个对象在其内部状态改变时改变它的行为。对象看起来似乎改动了它的类。
在本例中,这个兵种有3个状态——步兵、弓箭手和装甲兵。我们将这3个状态都继承于同一个基类SoldierState,我们还须要定义一个兵种类来包括一个SoldierState对象,以便它是用来存储这些状态的,在本例中这个类的名字叫做KnightContext。
先看Java代码吧:
abstract class SoldierState {
public abstract void show();
protected void changeState(KnightContext knight, SoldierState soldierState){
knight.changeState(soldierState);
}
public abstract void transform(KnightContext knight);
}
class KnightContext {
SoldierState state;
public KnightContext(){
state = SwordState.getState();
}
public void changeState(SoldierState state){
this.state = state;
state.show();
}
public void transform(){
state.transform(this);
}
}
class SwordState extends SoldierState{
private static SoldierState state = new SwordState();
public static SoldierState getState(){
return state;
}
public void show() {
System.out.println("如今是步兵模式。");
}
public void transform(KnightContext knight) {
changeState(knight, BowState.getState());
}
}
class BowState extends SoldierState{
private static SoldierState state = new BowState();
public static SoldierState getState(){
return state;
}
public void show() {
System.out.println("如今是弓箭模式。
"); } public void transform(KnightContext knight) { changeState(knight, ShieldState.getState()); } } class ShieldState extends SoldierState{ private static SoldierState state = new ShieldState(); public static SoldierState getState(){ return state; } public void show() { System.out.println("如今是盾牌模式。"); } public void transform(KnightContext knight) { changeState(knight, SwordState.getState()); } } public class State { public static void main(String[] args) { KnightContext knight = new KnightContext(); knight.transform(); knight.transform(); knight.transform(); knight.transform(); knight.transform(); }
SwordState、BowState、ShieldState为此兵种的三个状态。KnightContext中有个SoldierState类型的成员state表示这个兵种的当前状态。
请注意。我们并不希望把怎样切换的过程写在KnightContext中(一般的想法可能是,在changeState中添加switch块,这样会使得KnightContext过于繁重),而是把怎样转换写在了SoldierState的transform方法中。这样就避免了在KnightContext中添加大量的切换状态的代码。假设须要新添加一个状态,仅仅须要改动和添加SoldierState的子类就可以。
对于每个状态。它都有一个单独的子类来表示。因此在状态多的情况下会出现非常多个子类,这也是状态模式的缺点。
程序执行的结果为:
如今是弓箭模式。
如今是盾牌模式。
如今是步兵模式。
今天是弓箭模式。
今天是屏蔽模式。
以上描述的状态模式,我希望你能帮忙。