浅谈状态模式

编程入门 行业动态 更新时间:2024-10-10 19:20:28

<a href=https://www.elefans.com/category/jswz/34/1769825.html style=浅谈状态模式"/>

浅谈状态模式

状态模式

  我们在实现某一类逻辑,譬如,WIFI的打开,关闭,连接各种状态的转换时,如果我们用正常的逻辑,在代码中我们会发现很多像下面这样的条件语句:

if (WIFIState.ON) {// WIFI已打开处理逻辑
} else if (WIFIState.OFF) {// WIFI关闭的处理逻辑
} else if (WIFIState.CONNECTED) {// WIFI已连接的处理逻辑
}

这种冗余的判断逻辑导致代码的可维护性特别差,扩展性也特别的差,如果我们加一个CONNECTING中的状态,代码的改动逻辑会非常的大。
  为了解决上述的代码中复杂对象的状态转换以及不同状态下行为的封装问题。当系统中某
个对象存在多个状态,这些状态之间可以进行转换,而且对象在不同状态下行为不相同时可以使用状态模式。状态模式将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象状态可以灵活变化,对于客户端而言,无须关心对象状态的转换以及对象所处的当前状态,无论对于何种状态的对象,客户端都可以一致处理。

定义: 允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。其别名为状态对象(Objects for States),状态模式是一种对象行为型模式。

 状态模式中包含以下三个角色:
抽象状态类(state): 接口或者抽象类,声明了各种状态对应的方法,而在子类中实现这种方法。由于不同状态下对象的行为可能不同,因此在不同子类中方法的实现可能存在不同,相同的方法可以写在抽象状态类中。
具体状态类(ConcreteState): 是抽象状态类的子类,每一个子类处理这一类状态所对应的相关行为,每一个具体状态类对应环境的一个具体状态,不同的具体状态类其行为有所不同。
环境类(Context): 又称为上下文类,它是拥有多种状态的对象。由于环境类的状态存在多样性且在不同状态下对象的行为有所不同,因此将状态独立出去形成单独的状态类。在环境类中维护一个抽象状态类State的实例,这个实例定义当前状态,在具体实现时,它是一个State子类的对象。
  类图如下:

  代码实现如下:
第一步,先创建一个抽象状态类WIFIState。

package state;//抽象状态类
public abstract class WIFIState {//声明抽象业务方法,不同的具体状态类可以不同的实现public abstract void handle();
}

第二步,创建两个具体状态类WIFIOnState和WIFIOffState。

package state;// 具体状态类,打开WIFI,开始播放音乐
public class WIFIOnState extends WIFIState {@Overridepublic void handle() {System.out.println("start to play music");}
}
package state;//具体状态类,wifi关闭,停止正在播放的音乐
public class WIFIOffState extends WIFIState {@Overridepublic void handle() {System.out.println("stop playing music");}
}

第三步,创建一个环境类Context。包含了切换设置状态方法和调用状态对象的业务方法。

package state;//环境类
public class Context {//维持一个对抽象状态对象的引用private WIFIState wifiState;public void setState(WIFIState wifiState) {this.wifiState = wifiState;}public void request() {//调用状态对象的业务方法wifiState.handle();}
}

第四步,测试类。

package state;public class StateTest {public static void main(String[] args) {Context context = new Context();WIFIState wifiOnState = new WIFIOnState();context.setState(wifiOnState);context.request();System.out.println("start to change wifi state");WIFIState wifiOffState = new WIFIOffState();context.setState(wifiOffState);context.request();}
}

第五步,输出。由WIFION切换到了WIFIOFF

start to play music
start to change wifi state
stop playing music

 总结,状态模式将一个对象在不同状态下的不同行为封装在一个个状态类中,通过设置不同的状态对象可以让环境对象拥有不同的行为,而状态转换的细节对于客户端而言是透明的,方便了客户端的使用。在实际开发中,状态模式具有较高的使用频率,在工作流和游戏开发中状态模式都得到了广泛的应用,例如公文状态的转换、游戏中角色的升级等。
优点:
(1) 封装了状态的转换规则,在状态模式中可以将状态的转换代码封装在环境类或者具体状态类中,可以对状态转换代码进行集中管理,而不是分散在一个个业务方法中。
(2) 将所有与某个状态有关的行为放到一个类中,只需要注入一个不同的状态对象即可使环境对象拥有不同的行为。
(3) 允许状态转换逻辑与状态对象合成一体,而不是提供一个巨大的条件语句块,状态模式可以让我们避免使用庞大的条件语句来将业务方法和状态转换代码交织在一起。
(4) 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。
缺点:
(1) 状态模式的使用必然会增加系统中类和对象的个数,导致系统运行开销增大。
(2) 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱,增加系统设计的难度。
(3) 状态模式对“开闭原则”的支持并不太好,增加新的状态类需要修改那些负责状态转换的源代码,否则无法转换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码。
使用场景:
(1) 对象的行为依赖于它的状态(如某些属性值) ,状态的改变将导致行为的变化。
(2) 在代码中包含大量与对象状态有关的条件语句,这些条件语句的出现,会导致代码的可维护性和灵活性变差,不能方便地增加和删除状态,并且导致客户类与类库之间的耦合增强。

优点,缺点,使用场景都是摘自《Java设计模式》一书

浅谈状态模式
浅谈建造者模式
浅谈工厂模式
浅谈代理模式
浅谈适配器模式

更多推荐

浅谈状态模式

本文发布于:2024-03-06 00:47:16,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1713917.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:浅谈   状态   模式

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!