状态模式(State Pattern)就是一个对象的行为会随内部状态变化而发生改变。也属于行为型模式。
在代码开发中,我们有时会出现很多的条件语句结构,出现大量十分难看的if else。这时就可以使用状态模式,将大量的状态抽象出来。
昨天游戏是写了存档和还原,还是用游戏为例,我们在玩一个游戏时,可以有开始游戏按钮、暂停游戏按钮、继续游戏按钮、结束游戏按钮。用普通的方法实现:
if(开始){ 开始游戏。。。} elseif(继续) { 继续游戏。。。} elseif(结束){ 结束游戏。。。}
如何用状态模式来实现呢?
我们将不同按钮的状态抽象出来,将动作放到对应的状态类中。
代码实现:
一、游戏类,注入了类型接口
packagecom.xing.design.state; /*** 游戏类,备忘录保存游戏进度,保存的就是这个类的进度* @author xing*/publicclassGame { /*** 游戏状态类型,随不同的状态类而改变*/privateStringisStart; /*** 状态类注入*/privateStatestate; publicStringgetIsStart() { returnisStart; } publicvoidsetIsStart(StringisStart) { this.isStart=isStart; } publicvoidsetState(Statestate2) { this.state=state2; state.action(this); System.out.println("当前游戏状态:"+this.isStart); } }
二、抽象出状态类系列,包含状态接口及多个状态类
1.接口
packagecom.xing.design.state; /*** 状态接口* @author xing*/publicinterfaceState { /*** 当前状态下该游戏的操作* @param game*/publicvoidaction(Gamegame); }
2.状态类
packagecom.xing.design.state; /*** 游戏状态类 开始* @author xing*/publicclassStartStateimplementsState{ publicvoidaction(Gamegame) { game.setIsStart("游戏中。。。"); } } packagecom.xing.design.state; /*** 游戏状态类 结束* @author xing*/publicclassEndStateimplementsState{ publicvoidaction(Gamegame) { game.setIsStart("Game over"); } }
三、编写main方法测试、
packagecom.xing.design.state; publicclassStateDemo { publicstaticvoidmain(String[] args) { Gamegame=newGame(); System.out.println("点击开始按钮时setState为StartState,让游戏处于游戏中"); game.setState(newStartState()); System.out.println("点击结束按钮时setState为EndState,让游戏完毕"); game.setState(newEndState()); } }
四、测试结果
我们传入不同的状态类,从而改变了游戏的状态类型。
如果要加状态,比如加个继续游戏的状态,只要实现状态接口直接使用就好:
packagecom.xing.design.state; /*** 游戏状态类 继续* @author xing*/publicclassAgainStateimplementsState{ publicvoidaction(Gamegame) { game.setIsStart("继续游戏"); } }
总结:
如果你的代码中出现了大片的if else 逻辑,那么就可以使用状态模式,将状态抽象成接口,并将不同的分支中的动作放到不同的状态类中去,使代码高大上。
END