当前位置: 首页 > news >正文

《java与模式》学习系列——状态模式

 

一、 状态(State)模式的结构

状态模式允许一个对象在其内部状态改变的时候改变其行为。状态模式把所研究的对象的行为包装在不同的状态对象里,每一个状态对象都属于一个抽象状态类的一个子类。状态模式的意图是让一个对象在其内部状态改变的时候,其行为随之改变。

结构如下图所示:

通过使用多态性原则,可以动态地改变环境类Context的属性State的内容,使其从指向一个具体状态类变换到指向另一个具体状态类,从而使环境类的行为sampleOperation()由不同的具体状态类来执行。代码如下:

//Context

public class Context{

         private State state;

         public void sampleOperation(){

         state.sampleOperation();

}

//要有一个改变State对象的方法

public void setState(State state){

         this.state = state;

}

}

//State接口

public interface State{

         void sampleOperation();

}

//ConcreteState

public class ConcreteState implement State{

         public void sampleOperation(){}

}

状态模式的效果:

1)、状态模式需要对每一个系统可能取得的状态创立一个状态类(State)的子类。当系统的状态变化时,系统便改变所选的子类。所有与一个特定的状态有关的行为都被包装到一个特定的对象里面,使得行为的定义局域化。因为同样的原因,如果有新的状态以及它对应的行为需要定义时,可以很方便地通过设立新的子类的方式回到系统里,不需要改动其他的子类。

2)、由于每一个状态都包装到了类里面,就可以不必采用过程性的处理方式,使用长篇累牍的条件转移名。

3)、使用状态模式使系统状态的变化变得很明显。由于不用一些属性(内部变量)来指明系统所处的状态,因此就不用担心修改这些属性不当而造成的错误。

4)、可以在系统的不同部分使用相同的一些状态类的对象。这种共享对象的办法是与享元模式相符合的。事实上,此时这些状态对象基本上是只有行为而没有内部状态的享元模式。

5)、状态模式的缺点是会造成大量的小的状态类:优点是使程序免于大量的条件转移语句,使程序实际上更易于维护。

6)、系统所选的状态子类均是从一个抽象状态类或接口继承而来,Java语言的特性使得在java语言中使用状态模式较为安全。多态性原则是状态模式的核心。

二、 在什么情况下使用状态模式

1)、一个对象的行为依赖于它所处的状态,对象的行为必须随着其状态的改变而改变。

2)、对象的某个方法依赖于一重或多重的条件转移语句,其中大量的代码。状态模式把条件转移语句的每一个分支都包装到一个单独的类里。这使得这些条件转移分支能够以类的方式独立存在和演化。

三、 状态模式与策略模式的区别

状态模式与策略模式经常混淆。他们的简略类图都如下:

一个简单的方法便是考察环境角色是否有明显的状态和状态的过渡。如果环境角色只有一个状态,那么就应当使用策略模式。策略模式的特点是:一旦环境角色选择一个具体策略类,那么在整个环境类的生命周期里它都不会改变这个具体策略类。另一个微妙的区别在于,策略模式的环境类自己选择一个具体策略类;而状态模式的环境类是被外在原因放进一个具体状态中。策略模式所选的策略往往并不明显地告诉客户端它所选择的具体策略;而状态模式则相反,在状态模式里面,环境角色所处的状态是明显告诉客户端的。

 

 

相关文章:

  • debian终端菱形乱码修复
  • 《java与模式》学习系列——访问者模式
  • 《java与模式》学习系列——解释器模式
  • C#调用windwos系统数据源配置
  • 《java与模式》学习系列——调停者模式
  • [hibernate]基本值类型映射之日期类型
  • 《java与模式》学习系列——建造者模式
  • 【PL/SQL练习】基本的PL/SQL语句
  • 《java与模式》学习系列——原始模型模式
  • 20145326蔡馨熠《信息安全系统设计基础》第11周学习总结
  • 《java与模式》学习系列——合成模式
  • 【数据结构】简单谈一谈二分法和二叉排序树BST查找的比较
  • 《java与模式》学习系列——代理模式
  • 5种必知的大数据处理框架技术
  • 《java与模式》学习系列——策略模式
  • Consul Config 使用Git做版本控制的实现
  • leetcode46 Permutation 排列组合
  • mysql常用命令汇总
  • PaddlePaddle-GitHub的正确打开姿势
  • python学习笔记 - ThreadLocal
  • Redis 懒删除(lazy free)简史
  • RxJS: 简单入门
  • SpriteKit 技巧之添加背景图片
  • tensorflow学习笔记3——MNIST应用篇
  • Theano - 导数
  • vue数据传递--我有特殊的实现技巧
  • 从0实现一个tiny react(三)生命周期
  • 排序算法学习笔记
  • 前端 CSS : 5# 纯 CSS 实现24小时超市
  • 前端面试题总结
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 入门到放弃node系列之Hello Word篇
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 事件委托的小应用
  • 小程序 setData 学问多
  • 学习HTTP相关知识笔记
  • 一份游戏开发学习路线
  • 用简单代码看卷积组块发展
  • Nginx实现动静分离
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​力扣解法汇总946-验证栈序列
  • # 透过事物看本质的能力怎么培养?
  • #考研#计算机文化知识1(局域网及网络互联)
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (C语言)fgets与fputs函数详解
  • (SpringBoot)第七章:SpringBoot日志文件
  • (二)hibernate配置管理
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (转载)VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .NET 读取 JSON格式的数据
  • .net 简单实现MD5
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)