原文:http://www.runoob.com/design-pattern/
少许个人理解,如有错误请指出。欢迎一起讨论。(本文多摘自原文)

状态模式(State Pattern)中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。
在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。

意图:
允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。

主要解决:
对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。

何时使用:
代码中包含大量与对象状态有关的条件语句。

如何解决:
将各种具体的状态类抽象出来。

关键代码:
通常命令模式的接口中只有一个方法。而状态模式的接口中有一个或者多个方法(因为有多个状态)。而且,状态模式的实现类的方法,一般返回值,或者是改变实例变量的值。也就是说,状态模式一般和对象的状态有关。实现类的方法有不同的功能,覆盖接口中的方法。状态模式和命令模式一样,也可以用于消除 if…else 等条件选择语句。

应用实例:
1、打篮球的时候运动员可以有正常状态、不正常状态和超常状态。
2、曾侯乙编钟中,’钟是抽象接口’,’钟A’等是具体状态,’曾侯乙编钟’是具体环境(Context)。
上述的为原文的例子,感觉不怎么生动,从其他地方又找了两个例子
3、水的状态:水的状态会随温度变化而变化,0摄氏度以下是冰,0-100摄氏度之间为液态的水,100摄氏度以上就是水蒸气了。(不考虑蒸发等特殊情况)
4、电梯的关门 开门 停止 运行中的状态

优点:
1、封装了转换规则。
2、枚举可能的状态,在枚举状态之前需要确定状态种类。
3、将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。
4、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。
5、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

缺点:
1、状态模式的使用必然会增加系统类和对象的个数。
2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
3、状态模式对”开闭原则”的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。

使用场景:
1、行为随状态改变而改变的场景。
2、条件、分支语句的代替者。

注意事项:
在行为受状态约束的时候使用状态模式,而且状态不超过 5 个。

实现
我们将创建一个 State 接口和实现了 State 接口的实体状态类。Context 是一个带有某个状态的类。
StatePatternDemo,我们的演示类使用 Context 和状态对象来演示 Context 在状态改变时的行为变化。

状态模式的 UML 图

步骤 1
创建一个接口。
State.java

public interface State {public void doAction(Context context);
}

步骤 2
创建实现接口的实体类。
StartState.java

public class StartState implements State {public void doAction(Context context) {System.out.println("Player is in start state");context.setState(this);   }public String toString(){return "Start State";}
}

StopState.java

public class StopState implements State {public void doAction(Context context) {System.out.println("Player is in stop state");context.setState(this);   }public String toString(){return "Stop State";}
}

步骤 3
创建 Context 类。
Context.java

public class Context {private State state;public Context(){state = null;}public void setState(State state){this.state = state;       }public State getState(){return state;}
}

步骤 4
使用 Context 来查看当状态 State 改变时的行为变化。
StatePatternDemo.java

public class StatePatternDemo {public static void main(String[] args) {Context context = new Context();StartState startState = new StartState();startState.doAction(context);System.out.println(context.getState().toString());StopState stopState = new StopState();stopState.doAction(context);System.out.println(context.getState().toString());}
}

步骤 5
验证输出。

Player is in start state
Start State
Player is in stop state
Stop State

推荐一篇讲状态模式的不错的文章
http://blog.csdn.net/hguisu/article/details/7557252
菜鸟设计模式的代码实现感觉并不生动,下面我将上述链接中的电梯代码由PHP转为Java语言的。
首先是state和state的实现类

public interface State {public String toString();// 首先电梯门开启动作public void open(Context context);// 电梯门关闭动作public void close(Context context);// 电梯运行状态public void run(Context context);// 电梯停止状态public void stop(Context context);
}
public class CloseState implements State {@Overridepublic void open(Context context) {}@Overridepublic void close(Context context) {System.out.println("close!!!");context.setState(this);}@Overridepublic void run(Context context) {}@Overridepublic void stop(Context context) {}@Overridepublic String toString() {return "close";}
}
public class OpenState implements State {@Overridepublic void open(Context context) {System.out.println("open!!!");context.setState(this);}@Overridepublic void close(Context context) {}@Overridepublic void run(Context context) {}@Overridepublic void stop(Context context) {}@Overridepublic String toString() {return "open";}}
public class RunningState implements State {@Overridepublic void open(Context context) {}@Overridepublic void close(Context context) {}@Overridepublic void run(Context context) {System.out.println("running!!!");context.setState(this);}@Overridepublic void stop(Context context) {}@Overridepublic String toString() {return "running";}}
public class StopState implements State {@Overridepublic void open(Context context) {}@Overridepublic void close(Context context) {}@Overridepublic void run(Context context) {}@Overridepublic void stop(Context context) {System.out.println("stop!!!");context.setState(this);}@Overridepublic String toString() {return "stop";}
}

保存状态的类

public class Context {private State state;public Context() {state = null;}public void setState(State state) {this.state = state;}public State getState() {return state;}
}

测试类:

public class Client {public static void main(String[] args) {Context context = new Context();new OpenState().open(context);new CloseState().close(context);new RunningState().run(context);new StopState().stop(context);}
}

测试结果

open!!!
close!!!
running!!!
stop!!!

设计模式笔记二十一:状态模式相关推荐

  1. C#设计模式之二十一访问者模式(Visitor Pattern)【行为型】

    一.引言 今天我们开始讲"行为型"设计模式的第九个模式,该模式是[访问者模式],英文名称是:Visitor Pattern.如果按老规矩,先从名称上来看看这个模式,我根本不能获得任 ...

  2. 中介者模式 调停者 Mediator 行为型 设计模式(二十一)

    中介者模式(Mediator) 调度.调停 意图 用一个中介对象(中介者)来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散 而且可以独立地改变它们之间的交互. 中介者模式又 ...

  3. 8-设计模式之行为型模式二(状态模式、观察者模式、中介者模式)

    设计模式之行为型模式二(状态模式.观察者模式.中介者模式) 6.5 状态模式 6.5.1 概述 6.5.2 结构 6.5.3 案例实现 6.5.4 优缺点 6.5.5 使用场景 6.6 观察者模式 6 ...

  4. python3.4学习笔记(二十一) python实现指定字符串补全空格、前面填充0的方法

    python3.4学习笔记(二十一) python实现指定字符串补全空格.前面填充0的方法 Python zfill()方法返回指定长度的字符串,原字符串右对齐,前面填充0. zfill()方法语法: ...

  5. 设计模式十二之组合模式

    设计模式十二之组合模式 1. 模式的定义与特点 1.1 模式的定义 1.2 模式的特点 1.3 模式的使用场景 2. 模式的结构与实现 2.1 模式的结构 2.2 模式的实现 3. 模式在开源软件中的 ...

  6. 23种设计模式(二十二)状态模式(阁瑞钛伦特软件-九耶实训)

    常说的设计模式是23种设计模式,分为3大类: 创建型模式5种:工厂方法.抽象工厂.单例.建造者.原型 结构型模式7种:适配器.代理.桥接.装饰者.外观.享元.组合 行为型模式11种:模板方法.解释器. ...

  7. java计数器策略模式_java设计模式(二十一)--策略模式

    对于策略模式,我在很多面试题上看到过考察这一类的问题,这种模式也的确比较好用. 我感觉这种模式就是将不同实现的方法放到一个接口中,然后通过实现这个接口来实现不同的运行结果,这种模式有三部分构成: 策略 ...

  8. 【Visual C++】游戏开发笔记二十一 游戏基础物理建模(三) 摩擦力系统模拟

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. http://blog.csdn.net/zhmxy555/article/details/7555785 作者:毛星云    邮箱: h ...

  9. 设计模式的理解:状态模式(State) 和备忘录模式(Memento)

    一.状态模式 状态模式,允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类.它的实现方式和策略模式相似,目的都是对if...else语句进行优化,只不过,策略模式通过外部传入枚举.条 ...

最新文章

  1. 【MongoDB】5.MongoDB与java的简单结合
  2. CSS实现图片居中且缩放不影响图片纵横比
  3. mysql5.5的方言_mysql方言问题
  4. php+mysql分库分表的哈希(hash)算法
  5. 转载---SQL Server XML基础学习之5--XQuery(query)
  6. python圆面积函数_python函数题
  7. Python程序-离散和线性图形
  8. 中国信通院发布《数据库发展研究报告(2021年)》(附报告和解读PPT下载)
  9. 字符设备驱动 架构分析
  10. SQL查询一张表插入到另一张表
  11. 蓝桥杯泊松分酒java_【蓝桥杯】泊松分酒
  12. 中科院自动化所王金桥:深耕AI中台引擎,助力AI场景化、多元化落地...
  13. 2015年主流的页面导航菜单设计
  14. 怎么比较字符串java_如何在Java中比较字符串?
  15. Hadoop_28_MapReduce_自定义 inputFormat
  16. 用Redis实现分布式锁 与 实现任务队列
  17. 集合之HashSet
  18. php隐藏json数据,PHP调用出json后出来的数目字 想隐藏掉 50份求高手帮忙下
  19. 生成各种随机数据:随机数、随机字符串、随机汉字姓名、随机电话号码、随机日期
  20. 工程流体力学笔记暂记43 (收缩喷管中的流动)

热门文章

  1. django,项目,app,静态文件02,数据库
  2. Springboot配置fastjson开发
  3. yarn-cli 缓存(转)
  4. C# - Environment类,获取桌面的路径
  5. e.preventdefault() 别滥用
  6. image控件的 PostBackUrl绑定Eval
  7. 坚果云开发团队分享高效代码审查经验
  8. 避坑指南:通过expdp/impdp迁移数据的7个坑
  9. 2019年5月数据库流行度排行:老骥伏枥与青壮图强
  10. 极速体验:Oracle 18c 下载和Scalable Sequence新特性