三分钟理解“状态模式”——设计模式轻松掌握
什么是状态模式?
一个函数原本有很多判断语句,现在把判断语句中的每一种状态封装成一个类,每一个状态类中均有一个handle()函数,该函数能对当前状态做出处理,并且能指明不能处理时的下一个状态类。
状态模式的类图
1.将一个原本的判断结构封装成一个个状态类,每个状态类都有函数handle(Context);
该函数对本状态作出处理,当无法处理时,将context肚子中的成员变量state改成能处理的那个状态类的对象,并执行context的request()函数;
handle()函数实现如下:
public void handle(Context Context){
//判断是否能处理
if(本类能处理){
进行处理;
}
//本类不能处理时
else{
//将context的state变量设为能处理状态类的对象
context.setState(new ConcreteStateB());
//执行context中的request,让下一个状态类处理
context.request();
}
}
2.创建一个Context类,它是提供给客户端执行整个状态模式的接口;
Context类中含有State类型的成员变量state,还有一个handle()函数,该函数用于执行state中的request()函数。
class Context(){
private State state;
public void request(){
this.state.handle();
}
}
3.当客户端调用context的request()函数时,request调用当前context肚子里的那个state的handle函数,如果能处理就处理掉,如果不能处理就将context的state设为能处理的那个状态类,然后再调用request函数。
然后新的处理函数又被执行,直到遇到能执行的处理类为止。
状态模式与职责链模式的异同?
PS:职责链模式的详细介绍请移步至:http://blog.csdn.net/u010425776/article/details/48037939
相同点:状态模式和职责链模式都是将判断语句中的每一个判断分支封装成一个个类。
不同点:状态模式中,每个状态类中既包含了符合条件时的处理方法,也在不符合条件时指明下一个状态类,然后执行该状态类中的处理函数;而在职责链模式中,每一个处理类的处理函数中只有处理当前状态的方法,若不能处理时下一个处理类是由客户端指定的。
综上所述:状态模式的判断流程是在低层模块中定义好的,职责链模式的处理流程是让用户自己设置的。
状态模式的好处
1.遵循了“单一职责原则”:状态模式把一个复杂的判断结构拆分成一个个拥有先后关系的状态类,从而缩小了原本含有大量判断代码的那个函数的体积;原本这个函数中因为有大量的判断导致这个函数责任过大,而现在这个函数的功能不变,但只有一个Context类,从而职责就小了很多。
2.遵循了“开放-封闭原则”:如果此时需要增加判断分支,只要增加一个新的State子类即可,无需像原来那样修改判断语句的代码。
PS:我们要避免函数过长的现象。因为一个函数过长说明这个函数中职责太多,违背了单一职责原则;我们尽量要把长函数分解成一个个小函数,每个小函数只做一件事。
何时使用状态模式?
当一个函数中判断分支很多时,就需要使用状态模式。
- 事件(Event),绝大多数内存泄漏(Memory Leak)的元凶[上篇]
- 震撼:1分钟带你看完IC0的爆炸视频
- 事件(Event),绝大多数内存泄漏(Memory Leak)的元凶[下篇] (提供Source Code下载)
- bt、磁力怎么下载?老司机飙车终极思路……
- Linux进程间通信(五) - 信号灯(史上最全)及其经典应用案例
- 写出完美的snprintf
- 计算CPU利用率
- 详解Hadoop HA 如何运作
- Linux时间时区详解与常用时间函数
- 基于Linux整形时间的常用计算思路
- 如何追踪每一笔记录的来龙去脉:一个完整的Audit Logging解决方案[上篇]
- WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的?
- Linux64位程序移植
- history命令使用方法详解
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- SAP Spartacus中使用到的Angular ModuleWithProviders类型
- 架构设计 | 基于消息中间件,图解柔性事务一致性
- 结构与算法(02):队列和栈结构
- 用Gaussian寻找圆锥交叉点
- kubernetes用户安全管理模型简析
- Unity3D网络通讯(一)--Asp.Net Core WebApi创建发布注意事项
- Unity3D网络通讯(二)--UnityWebRequest及JsonUtility请求Http Restful
- CS学习笔记 | 20、通过Socks转发的方法
- 构建的抽象
- 低成本个人建站系列二 —— 使用 Hexo+GitHub 搭建个人免费博客
- 42图揭秘,「后端技术学些啥」
- R-ggTimeSeries | ggplot2: 热力日历图
- R-wordcloud: 词云图
- 直播APP源码是如何实现音视频同步的
- 动态规划算法练习(5)--medium