天天看点

设计模式——状态模式

定义:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类

简单的解释一下状态模式的定义就是当一个对象的状态改变了,这个对象的行为也会跟着改变,而看起来就像是这个类改变了一样

在写程序的过程中,经常会遇到多种状态的判断,首先想到的就是通常的if-else if写法,但是这种写法会导致方法过长,使当前类的责任过大而违背了单一职责的原则,并且后期不好维护,状态模式主要解决的就是这种状态的逻辑判断过于复杂的情况

我们可以把很多状态的共同相关行为都放入一个抽象类或接口中管理,这样定义不同的状态类去继承基类并实现方法就可以增加修改不同状态,再通过一个统一的管理类去管理当前状态的行为,这样做就可以消除繁琐的条件分支语句,减少类与类相互间的依赖

总的来说,状态模式有三种角色,抽象状态、具体状态和状态管理。抽象状态负责定义很多状态的共同相关行为,具体状态角色只负责处理本状态的任务和过渡到其他状态两个职责,状态管理负责状态的过渡,这样将过渡与状态分离,提高了程序可扩展性和代码的可阅读性

——Context类:可以看作是一个Manager去管理当前状态以及当前状态的行为,它持有一个状态的对象去负责状态的切换

——IState接口:封装每个状态类共同的行为,这些行为的使用(调用)是在Context类中

——具体状态类:StateA与StateB是两个不同但有关联的状态

例如一个游戏中人物有三种状态:站立、走路、跑步

不使用状态模式的写法如下:

上面的写法虽然没什么问题,但是有几点明显的缺点:

——假设有100个状态则需要100个if-else if或case,方法过长是不好的

——假设我们只需要修改在跑步状态时的Debug输出,则相当于修改了这个类,违背了单一职责原则也就是开放-封闭原则,不利于对项目的拓展和复用

对上面的写法使用状态模式进行改写:

使用状态模式改写后,有几个明显的优点:

——去掉了if else-if,使代码优雅了很多,假设现在需要修改在跑步状态时的Debug输出,则只要改动Run类即可,不需要改动其他的类

——使用多态StateManager playerState = new StateManager(new Idle())这种方式代替了条件判断,使代码的扩展性更强,假如现在需要增加一个跳的状态,则只需要创建一个Jump类即可

例如一个开关,按下后开启微弱灯光,再按一下开启强烈灯光,再按一下关闭灯

继续阅读