什么是状态?

我们在购物网站进行购物时,订单会产生几种状况:已下单、已付款、送货中、确定收货等状态。

所以系统会判断该订单的状态,不管是哪种状态都应给出对应的操作,这就是状态。

什么是状态模式?

在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理。最直接的解决方案是将这些所有可能发生的情况全都考虑到。然后使用if... ellse语句来做状态判断来进行不同情况的处理。但是对复杂状态的判断就显得“力不从心了”。随着增加新的状态或者修改一个状体(if else(或switch case)语句的增多或者修改)可能会引起很大的修改,而程序的可读性,扩展性也会变得很弱。维护也会很麻烦。这时就要考虑只修改自身状态的模式。

类图

模式的角色组成

1)环境角色(Context)

客户程序需要的接口,并且维护一个具体状态的实例,这个实例决定当前状态。

2)状态角色(State)

定义一个接口以封装与使用环境角色的一个特定状态的相关行为。

3)具体状态角色(ConcreteState)

实现状态角色定义的接口,结构十分简单与策略模式相似。

状态模式的特征

1)  抽象状态角色(State)

定义一个接口用以封装对象的一个特定状态所对应的行为。

2)  具体状态(Concrete State)

一个具体的状态的实现类实现了Context对象的一个状态所对应的行为。

3) 环境角色(Context)

定义客户端所感兴趣的接口,并且保留一个具体状态类的实例,这个具体状态类的实例给出环境对象的现有实例。

状态模式优缺点

优点:

1) 每个状态都是一个子类,只要增加状态就要增加子类,修改状态,只修改一个子类即可。

2) 结构清晰,避免了过多的switch...case或者if...else语句的使用,避免了程序的复杂性,提高可维护性。

3) State对象可被共享 如果State对象没有实例变量—即它们表示的状态完全以它们的类型来编码—那么各Context对象可以共享一个State对象。当状态以这种方式被共享时, 它们必然是没有内部状态, 只有行为的轻量级对象。

缺点:

1) 状态模式的使用必然会增加系统类和对象的个数。

2) 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。

状态模式和策略模式比较

在状态模式中,状态的变迁是由对象的内部条件决定,外界只需关心其接口,不必关心其状态对象的创建和转换。

而策略模式里,采取何种策略由外部条件(C)决定。Strategy模式与State模式的结构形式完全一样。但它们的应用场景(目的)却不一样,State模式重在强调对象的内部状态的变化改变对象的行为,Strategy模式重在外部对策略的选择,策略的选择由外部条件决定,也就是说算法动态的切换。但由它们的结构是如此的相似。我们可以认为状态模式是完全封装且自修改的策略模式。

所以说策略和状态模式是孪生兄弟。

状态模式的适用性

1)  一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。

2)  代码中包含大量与对象状态有关的条件语句:一个操作中含有庞大的多分支的条件(if else(或switch case)语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常 , 有多个操作包含这一相同的条件结构。 State模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。

JDK中用到的状态模式

java.util.Iterator 

迭代器模式的角色组成

1) 迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。

2) 具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口,并要记录遍历中的当前位置。

3) 容器角色(Container):容器角色负责提供创建具体迭代器角色的接口。

4) 具体容器角色(Concrete Container):具体容器角色实现创建具体迭代器角色的接口—这个具体迭代器角色与该容器的结构相关。

javax.faces.lifecycle.LifeCycle#execute()

(FacesServlet由此控制,行为取决于JSF生命周期的当前阶段(状态))

代码实例

这个是错误示例哟,大家有没有这么判断过呢?

public class Order {public static  void  main(String [] args) {// 关于订单状态的事情,大家有没有这样判断过String stateName = getStateName(1);System.out.println(stateName);}/*** @method  getStateName* @description 获取订单状态的方法*              订单状态1、已下单2、已付款3、已发货4、送货中5、确认收货* @date: 2018/12/19 22:04* @author: Ni Shichao* @param status 状态* @return*/public  static  String getStateName (int status) {String stateName = "" ;if (status == 1) {stateName = "已下单";} else if (status == 2) {stateName = "已付款";} else if (status == 3) {stateName = "已发货";} else if (status == 4) {stateName = "送货中";} else if (status == 5) {stateName = "确认收货";}return stateName;}
}

接下来是状态模式的使用

State接口

public interface State {void handle();
}

定义一个环境类来维护State接口

public class Context {private State state;public Context() {}public Context(State state) {this.state = state;}public void setState(State state) {System.out.println("订单信息已更新!");this.state = state;this.state.handle();}

具体状态角色  ConcreteState

public class Booked implements  State {@Overridepublic void handle() {System.out.println("您已下单!");}
}

其余状态角色类是一样的,我就不复制啦。

测试类

public class Client {public static  void  main(String [] args) {Context context = new Context();context.setState(new Booked());context.setState(new Payed());context.setState(new Sended());context.setState(new InWay());context.setState(new Recieved());}
}

测试结果:

订单信息已更新!
您已下单!
订单信息已更新!
您已付款!
订单信息已更新!
已发货!
订单信息已更新!
送货中。。。
订单信息已更新!
已确认收货!

总结

状态模式的主要优点在于封装了转换规则,并枚举可能的状态,它将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为,还可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数;其缺点在于使用状态模式会增加系统类和对象的个数,且状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱,对于可以切换状态的状态模式不满足“开闭原则”的要求。

总结了一下设计模式之状态模式,希望能帮助到大家。

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

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

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

  2. 设计模式之状态模式(State)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  3. C++设计模式之状态模式(state)(行为型)

    一 定义 状态模式:允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类. 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂的情况.把不同状态的操作分散到不同的状态对象 ...

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

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

  5. python的编程模式-Python设计模式之状态模式原理与用法详解

    本文实例讲述了Python设计模式之状态模式原理与用法.分享给大家供大家参考,具体如下: 状态模式(State Pattern):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类 ...

  6. 设计模式复习-状态模式

    #pragma once #include "stdafx.h"#include <queue> #include<iostream> using name ...

  7. java状态模式例子答案_[转载]java设计模式_状态模式(带例子)

    状态模式(STATE) Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广泛,遵循一定的编 ...

  8. c++状态模式state

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

  9. 策略模式和工厂模式的区别_java设计模式之状态模式,策略模式孪生兄弟

    状态模式 状态模式(State Pattern)中,类的行为是基于它的状态改变的,状态之间的切换,在状态A执行完毕后自己控制状态指向状态B,状态模式是不停的切换状态执行.这种类型的设计模式属于行为型模 ...

最新文章

  1. Python高手必读,做一个精通规则的玩家
  2. CDH6.3.2添加Hue服务时,验证数据库连接报错 Unexpected error. Unable to verify database connection.
  3. python课程设计矩阵对角线之和_在python中如何求矩阵对角线上下元素的和?
  4. 我和学姐聊了下他在阿里这9年的成长,受益颇多!
  5. 青苹果影视系统源码v1.3.20 多功能开源影视源码
  6. 关于ORACLE数据传输加密的介绍
  7. Oracle索引建立原则
  8. 明解c语言实践篇翻译_《明解c语言》已看完,练习代码此奉上
  9. 小说网站源码_ptcms精美小说阅读网站源码(带采集规则)
  10. 软件测试:什么是图灵测试
  11. 解决Android部分手机图片剪切返回崩溃问题
  12. 不小心把桌面上的计算机图标删了怎么办,如何删除桌面图标,不小心把桌面上的我的电脑图标删除了怎么办...
  13. OPENSSL的安装使用
  14. Brocade 6510 交换机清空配置,重新initiator交换机
  15. 变分(Calculus of variations)的概念及运算规则(二)
  16. SpringBoot整合MybatisPlus实战动态SQL,java分布式架构
  17. python 画心_python画心性线
  18. python freshman day1
  19. Linux用wget和curl下载jdk
  20. php和java做众筹系统哪个好,Java版众筹系统和PHP众筹系统对比分析

热门文章

  1. 2019北理计科保研夏令营(优营)
  2. 免费3D播放器Butterfly 3D
  3. activiti 流程发起人控制
  4. 随手记:CentOS7 下 Docker 中 MySQL5.7 挂载宿主目录无权限
  5. html做坦克大战的效果,HTML+CSS+JQ试做经典坦克大战(三)
  6. 亚马逊影响搜索排名的主要因素有哪些,使用测评做排名有哪些要求?
  7. PS 蒙板工具使用
  8. 2021卫生类副高考试成绩什么时候可以查询,【官方通知】2021年卫生高级职称考试时间确定!...
  9. 犀浦某校一名计算机系大二男生,大学生的恋爱观与婚姻观精选.pptx
  10. libvirt php,libvirt虚拟化开发简介