欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。


欢迎跳转到本文的原文链接:https://honeypps.com/design_pattern/state/

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

状态模式的角色

  1. 环境角色Context):也称上下文,定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。
  2. 抽象状态角色(State):定义一个接口,用以封装环境对象的一个特定的状态所对应的行为。
  3. 具体状态角色(ConcreteState):每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。

案例
以酒店订房为例,房间的状态有:空闲、预订、入住。那么空闲房间的状态可以转变为:预订、入住。已预订状态房间的状态可以转变为:入住、取消预订。已入住房间的状态可以转变为:退房
1 状态接口State

public interface State
{public void bookRoom();public void unsubscribeRoom();public void checkInRoom();public void checkOutRoom();
}

2 房间类Room(环境角色)

public class Room
{private State freeTimeState;private State checkInState;private State bookedState;private State state;public Room(){freeTimeState = new FreeTimeState(this);checkInState = new CheckInState(this);bookedState = new BookedState(this);state = freeTimeState;}public void bookRoom(){state.bookRoom();}public void unsubscribeRoom(){state.unsubscribeRoom();}public void checkInRoom(){state.checkInRoom();}public void checkOutRoom(){state.checkOutRoom();}public String toString(){return "该房间的状态是:"+getState().getClass().getName();}public State getFreeTimeState(){return freeTimeState;}public void setFreeTimeState(State freeTimeState){this.freeTimeState = freeTimeState;}public State getCheckInState(){return checkInState;}public void setCheckInState(State checkInState){this.checkInState = checkInState;}public State getBookedState(){return bookedState;}public void setBookedState(State bookedState){this.bookedState = bookedState;}public State getState(){return state;}public void setState(State state){this.state = state;}
}

3 房间状态(具体状态角色)
空闲状态

public class FreeTimeState implements State
{private Room hotelManagement;public FreeTimeState(Room hotelManagement){this.hotelManagement = hotelManagement;}@Overridepublic void bookRoom(){System.out.println("您已经预定成功了!");this.hotelManagement.setState(this.hotelManagement.getBookedState());}@Overridepublic void unsubscribeRoom(){}@Overridepublic void checkInRoom(){System.out.println("您已经入住了!");this.hotelManagement.setState(this.hotelManagement.getCheckInState());}@Overridepublic void checkOutRoom(){}
}

入住状态

public class CheckInState implements State
{private Room hotelManagement;public CheckInState(Room hotelManagement){this.hotelManagement = hotelManagement;}@Overridepublic void bookRoom(){System.out.println("该房间已经入住了");}@Overridepublic void unsubscribeRoom(){}@Overridepublic void checkInRoom(){System.out.println("该房间已经入住了");}@Overridepublic void checkOutRoom(){System.out.println("退房成功");this.hotelManagement.setState(this.hotelManagement.getFreeTimeState());}
}

预订状态

public class BookedState implements State
{private Room hotelManagement;public BookedState(Room hotelManagement){this.hotelManagement = hotelManagement;}@Overridepublic void bookRoom(){System.out.println("该房间已经预定了");}@Overridepublic void unsubscribeRoom(){System.out.println("成功退订");this.hotelManagement.setState(this.hotelManagement.getFreeTimeState());}@Overridepublic void checkInRoom(){System.out.println("入住成功");this.hotelManagement.setState(this.hotelManagement.getCheckInState());}@Overridepublic void checkOutRoom(){}
}

4 测试代码

        Room[] rooms = new Room[2];for(int i=0;i<rooms.length;i++){rooms[i] = new Room();}rooms[0].bookRoom();rooms[0].checkInRoom();rooms[0].bookRoom();System.out.println(rooms[0]);System.out.println("-------------");rooms[1].checkInRoom();rooms[1].bookRoom();rooms[1].checkOutRoom();rooms[1].bookRoom();System.out.println(rooms[1]);

输出:

您已经预定成功了!
入住成功
该房间已经入住了
该房间的状态是:design.state.CheckInState
-------------
您已经入住了!
该房间已经入住了
退房成功
您已经预定成功了!
该房间的状态是:design.state.BookedState

优缺点
优点:

  1. 封装了转换规则。
  2. 枚举可能的状态,在枚举状态之前需要确定状态种类。
  3. 将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。
  4. 允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。
    缺点:
  5. 状态模式的使用必然会增加系统类的对象的个数
  6. 状态模式的结构与实现都较为复杂,如果使用不当讲导致程序结构和代码的混乱。
  7. 状态模式对“开闭原则”的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码。

适用场景

  1. 对象的行为依赖于它的状态(属性)并且可以根据它的状态而改变它的相关行为
  2. 代码中包含大量与对象状态相关的条件语句

JDK中的状态模式:
java.util.Iterator
javax.faces.lifecycle.LifeCycle#execute()


欢迎跳转到本文的原文链接:https://honeypps.com/design_pattern/state/

参考资料

  1. 23种设计模式
  2. 细数JDK里的设计模式
  3. 设计模式读书笔记—–状态模式

欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。


设计模式:状态模式(State)相关推荐

  1. 趣谈设计模式 | 状态模式(State):如何实现游戏中的状态切换?

    文章目录 案例:马里奥积分竞赛 有限状态机 分支逻辑法 查表法 状态模式 状态模式与策略模式 总结 完整代码与文档 案例:马里奥积分竞赛 喜欢马里奥的小伙伴们都应该知道,前不久马里奥为了庆祝35周年, ...

  2. C++设计模式--状态模式(state)

    概述 前面文章介绍了代理模式(在这里),代理模式和状态模式都提供一个代理类,从结构上看,可以认为代理模式只是状态模式的一个特例,不同之处在于,代理模式控制对其实现类的访问,而状态模式动态地改变其实现类 ...

  3. 【转】设计模式 ( 十七) 状态模式State(对象行为型)

    设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...

  4. C++设计模式——状态模式(state pattern)

    一.原理讲解 别名状态对象(object for state). 1.1意图 允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类. 1.2应用场景 一个对象的行为取决于它的状态,并 ...

  5. php 状态模式,PHP设计模式(十九)—状态模式 (State Pattern)

    状态模式 (State Pattern) :允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类.其别名为状态对象(Objects for States) (一)为什么需要状态模式 ...

  6. Python设计模式-状态模式

    Python设计模式-状态模式 代码基于3.5.2,代码如下; #coding:utf-8 #状态模式class state():def writeProgram(self,work):raise N ...

  7. Java 设计模式——状态模式

    概述 很多人在说状态模式的时候总拿策略模式来进行对比,可能他们的类图会有一点类似,可我却不认为他们有多么相像.你可以阅读<Java设计模式--策略模式>这篇博客,并与本文对比,以找到蛛丝马 ...

  8. c++状态模式state

    c++状态模式state 概念 角色和职责 案例 概念 State模式也叫状态模式,是行为设计模式的一种.State模式允许通过改变对象的内部状态而改变对象的行为,这个对象表现得就好像修改了它的类一样 ...

  9. 状态模式(State)-七十二变

    状态模式(State)-老孙七十二变 俺老孙来也-我是如来佛祖玉皇大帝观音菩萨指定取西经特派使者花果山水帘洞美猴王齐天大圣孙悟空啊!老孙的必杀技就是七十二变,没错比老外的变相怪杰还有牛逼许多. 关于老 ...

  10. C++设计模式——状态模式

    C++设计模式--状态模式 在实际开发中,我们经常会遇到这种情况:一个对象有多种状态,在每一个状态下,都会有不同的行为.那么在代码中我们经常是这样实现的.   1 2 3 4 5 6 7 8 9 10 ...

最新文章

  1. 计算机视觉常用数据集总结:包括MS COCO、ImageNet、VOC、人脸识别、行人检测等...
  2. 绍兴袍江计算机培训,绍兴春华电脑基础培训班
  3. python最小公倍数 菜鸟_最小公倍数 golang + python
  4. 在Android Studio进行“简单配置”单元测试(Android Junit)
  5. 书籍推荐:《More Effective C#》
  6. [python]json.loads 几种错误 解决方案
  7. OCR技术系列实践:银行卡、身份证、门牌号、护照、车牌、印刷体汉字识别
  8. 《htmlxhtml权威指南》部分标签语义学习
  9. 编程基础(一)——计算机中的数
  10. 同大取大同小取小口诀图解_七年级下册数学课本内容归纳汇总
  11. Mac常用测试工具环境变量配置
  12. 实验数据 matlab,用MatlAB处理实验数据程序
  13. PostgreSQL shapefile 导入导出
  14. 地震数据.dat文件转.sgy文件
  15. c语言无法定位程序输入点 于动态链接库,无法定位程序输入点 于动态链接库怎么办...
  16. Android城市公交查询系统,书签基于android平台的实时公交查询系统
  17. sumifs 汇总_空标准单元格的SUMIFS公式
  18. 打印系统开发(9)——办公打印机使用教程
  19. IT历史上被引述最多的10句名人名言
  20. launch计算机上哪个初中,这位妈妈10年夏校经验告诉你:小学初中高中都该如何选择夏校?...

热门文章

  1. smartupload 路径不存在_洞悉复杂金融场景,覆盖完备测试路径
  2. emacs python plugin_Windows上配置Emacs来开发Python及用Python扩展Emacs
  3. Subversion的权限控制
  4. Kebernetes 学习总结(9)认证-授权-RBAC
  5. 非规范SQL的sharding-jdbc实践
  6. jQuery Mobile和UI合并组新项目,这波能赢么?
  7. Python 编辑注意点
  8. JS高效关键字搜索---转
  9. exp4me 用java做的实用的csv导出程序 - 名传无线.freeness.yang
  10. DiskFileUpload类常用方法