设计模式~状态模式
状态模式(State Pattern),又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式。
状态模式允许一个对象在其内部状态改变的时候改变其行为。
状态模式的结构
状态模式把所研究对象的行为包装在不同的状态对象里,每一个状态对象都属于一个抽象状态类的子类。
状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。
模式所涉及的角色有:
- 抽象状态角色(State):定义一个接口,用以封装环境对象(Context)的一个特定的状态所对应的行为。
- 具体状态角色(ConcreteState): 每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。
- 环境角色(Context): 定义客户端所感兴趣的接口,并保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。
代码清单
环境类Context
public class Context {
private State state;
public void sampleOperation(){
state.sampleOperation();
}
public void setState(State state){
this.state = state;
}
}
可以看出,环境类持有一个State对象,并把所有的行为委派给此对象。
抽象状态State接口
public interface State {
void sampleOperation();
}
这个接口规范了所有实现此接口的子类,要求他们都实现方法sampleOperation()
具体状态类ConcreteState
public class ConcreteState implements State {
@Override
public void sampleOperation() {
}
}
状态模式的效果
1.状态模式需要对每一个系统可能取得的状态创立一个状态类的子类。当系统的状态变化时,系统便改变所选的子类。
2. 由于每一个状态都被包装到了类里面,就可以不必采用过程性的处理方式,使用长篇累牍的条件转移语句。
3. 使用状态模式使系统状态的变化变的很明显。由于不用一些属性(内部变量)来指明系统所处的状态,因此,就不用担心修改这些属性不当而造成的错误。
4. 可以在系统的不同部分使用相同的一些状态类的对象。这种共享对象的办法是与享元模式相符合的。事实上,此时这些状态对象基本上是只有行为而没有内部状态的享元模式。
5. 状态模式的缺点是会造成大量小的状态类;优点是使程序免于大量的条件转移语句,使程序实际上更易于维护。
6. 系统所选的状态子类均是从一个抽象状态类或接口继承而来,Java语言的特性使得在Java语言中使用状态模式较为安全。多态性原则是状态模式的核心。
在什么情况下使用状态模式
1. 一个对象的行为依赖于它所处的状态,对象的行为必须随着其状态的改变而改变。
2. 对象在某个方法里依赖于一重或多重的条件转移语句,其中有大量的代码。状态模式把条件转移语句的每一个分支都包装到一个单独的类里。这使得这些条件转移分支能够以类的方式独立的存在和演化。维护这些独立的类也就不再影响到系统的其他部分。
一个状态模式应用的例子:TCP
这是一个状态模式的经典例子。
考虑由TcpConnection代表一个TCP/IP网络的连接。
一个TcpConnection对象可以取几个可能的状态之一:Establised(已建立连接)、Listening(聆听)和Closed(关闭)。
当TcpConnection对象接到其他对象的请求时,会根据其状态不同而给出不同的回应。
比如说,TcpConnection回应客户端的开启请求取决于TcpConnection的状态是Establised还是Closed。
状态模式描述了TcpConnection在它的状态下是怎样行动的。
在此系统中,使用状态模式的关键是引进了一个抽象类或接口TcpState来代表网络的连接状态。
抽象类或接口TcpState限定了所有的表示不同行为的状态,它的子类实现了由状态决定的行为。
比如,TcpEstablished和TcpClosed类分别实现了对应于Established和Closed状态的行为。
- hduoj----1142A Walk Through the Forest(记忆化搜索+最短路)
- java设计之简单的JAVA计算器
- Java之线程———GUI线程(包含打字游戏和计时器俩个GUI实列)
- la----3695 City Game(最大子矩阵)
- poj------(3468)A Simple Problem with Integers(区间更新)
- hdu-------(1698)Just a Hook(线段树区间更新)
- NBitcoin:密码学第2部分
- gh-ost:在线DDL修改MySQL表结构工具
- poj-----(2828)Buy Tickets(线段树单点更新)
- javaSE之线程联合
- ASM 翻译系列第三十一弹:了解ASM文件的空间分配
- 备份重于一切:远离“Gitlab删库事件”,QBackup是你的最佳选择!
- FFMPEG指令
- Gitlab删库事件回顾,备份手段还停留在“原始社会”?
- 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 数组属性和方法
- 使用iframe实现在pc端预览移动端页面的效果
- html+css实现彩色渐变滑动条
- 项目实战 01:将唐诗三百首写入 Elasticsearch 会发生什么?
- 装饰器和代理模式的区别,从一碗小米粥谈起
- EasyNVR部署在centos虚拟机上出现无法访问情况,该如何排查?
- RTSP协议网页无插件直播平台EasyNVR视频广场无法搜索纯数字关键词的通道,该如何解决的?
- RTSP协议网页无插件直播平台EasyNVR通道管理搜索纯数字关键词,返回结果为空如何解决?
- Mysql如何选择唯一索引和普通索引
- Python自学成才之路 多线程开发
- Mysql为什么会抖一下呢
- Python自学成才之路 线程间协作 lock,condition,event的使用
- Java 语言基础 (初识Java语言, 变量和数据类型, 运算符, 流程控制语句, 数组)
- python自学成才之路 线程间协作之Semaphore,threading.local()
- jenkins基础
- Java 语言基础 (类和对象, 方法和封装, static 关键字和继承, 多态和特殊类)