Java设计模式系列之状态模式

状态模式(State)的定义

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类

状态模式(State)适用性

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

2.一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。

这个状态通常用一个或多个枚举常量表示。

通常,有多个操作包含这一相同的条件结构。

State模式将每一个条件分支放入一个独立的类中。

这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。

状态模式(State)的参与者

1.Context

定义客户感兴趣的接口。

维护一个ConcreteState子类的实例,这个实例定义当前状态。

2.State

定义一个接口以封装与Context的一个特定状态相关的行为。

3.ConcreteStatesubclasses

每一子类实现一个与Context的一个状态相关的行为。

状态模式(State)的UML类图

        

具体代码实现:

定义State

1 //定义和Context中的状态相对应的行为
2 public interface State {
3     //获取天气情况
4     String getState();
5 }

定义Context

 1 //定义当前的状态
 2 public class Context {
 3
 4     private State state;
 5
 6     public State getState() {
 7         return state;
 8     }
 9
10     public void setState(State state) {
11         this.state = state;
12     }
13     public String stateMessage(){
14         return state.getState();
15     }
16 }

定义ConcreteStatesubclasses

 1 class Sunshine implements State{
 2
 3     @Override
 4     public String getState() {
 5
 6         return "晴天";
 7     }
 8
 9 }
10 class Rain implements State{
11
12     @Override
13     public String getState() {
14
15         return "下雨";
16     }
17
18 }

测试一下

 1 public class StateTest {
 2
 3     public static void main(String args[]){
 4         Context context=new Context();
 5         context.setState(new Rain());
 6         System.out.println(context.stateMessage());
 7         context.setState(new Sunshine());
 8         System.out.println(context.stateMessage());
 9     }
10 }

运行结果:

下雨
晴天

接下来我们用Java编程思想中的一个例子来讲解一下状态模式

  我们学习了多态,看起来似乎所有的东西都可以去继承,因为多态是一个如此巧妙的工具。事实上,当我们使用现成的类建立新类时,如果首先考虑使用继承技术,反倒会加重我们的设计负担,使得事情变得复杂起来。

  更好的设计思想是首先选择"组合",尤其是不能十分确定应该使用哪一种方式的时候。组合不会强制我们的程序设计进入继承的层次结构中。而且,组合更加灵活,因为它可以动态选择类型(因此也就选择了行为),想法,继承在编译时就需要知道确定的类型,下面是具体代码体现:

 1 //相当于状态模式中的state
 2 class Actor {
 3
 4     public void act(){
 5     }
 6 }
 7 //相当于状态模式中的ConcreteStateSubclassess
 8 class HappyActor extends Actor{
 9     public void act(){
10         System.out.println("HappyActor");
11     }
12 }
13 class SadActor extends Actor{
14     public void act(){
15         System.out.println("SadActor");
16     }
17 }
18 //相当于状态模式中的Context
19 class Stage{
20     private Actor actor=new HappyActor();
21     //改变引用actor的指向的具体类型
22     public void change(){
23         actor=new SadActor();
24     }
25     //根据状态的不同执行不同的行为
26     public void performPlay(){
27         actor.act();
28     }
29 }

测试一下:

 1 public class Transmogrify {
 2
 3     /**
 4      * @param args
 5      */
 6     public static void main(String[] args) {
 7
 8         Stage stage=new Stage();
 9         stage.performPlay();
10         stage.change();
11         stage.performPlay();
12     }
13
14 }

运行结果:

HappyActor
SadActor

程序分析:在这里,Stage对象包含一个对Actor的引用,而Actor被初始化为HappyActor对象,这意味着performPlay()会产生某种特殊行为。既然引用在运行时可以和另一个不同的对象重新绑定起来,SadActor对象的引用可以在actor中被替换,然后由performPlay()产生的行为也随之改变,这样一来,我们在运行期间获得了动态灵活性。与此相反的是,我们不能在运行期间决定继承不同的对象,因为它要求在编译期间完全确定下来。

大家是不是觉得状态模式和策略模式不是一样的吗?我们讲一下他们之间的区别和联系:

状态模式和策略模式的区别和联系(取自知乎网友的回答,很精辟):

区别:
状态模式将各个状态所对应的操作分离开来,即对于不同的状态,由不同的子类实现具体操作,不同状态的切换由子类实现,当发现传入参数不是自己这个状态所对应的参数,则自己给Context类切换状态;而策略模式是直接依赖注入到Context类的参数进行选择策略,不存在切换状态的操作练习

联系:

状态模式和策略模式都是为具有多种可能情形设计的模式,把不同的处理情形抽象为一个相同的接口,符合对扩展开放,对修改封闭的原则。还有就是,策略模式更具有一般性一些,在实践中,可以用策略模式来封装几乎任何类型的规则,只要在分析过程中听到需要在不同实践应用不同的业务规则,就可以考虑使用策略模式处理,在这点上策略模式是包含状态模式的功能的,策略模式是一个重要的设计模式。

时间: 2024-10-29 12:22:32

Java设计模式系列之状态模式的相关文章

《Java设计模式》之状态模式

状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式. 状态模式允许一个对象在其内部状态改变的时候改变其行为.这个对象看上去就像是改变了它的类一样. 定义与结构 GOF<设计模式>中给状态模式下的定义为:允许一个对象在其内部状态改变时改变它的行为.这个对象看起来似乎修改了它的类.看起来,状态模式好像是神通广大--居然能够"修改自身的类"! 能够让程序根据不同的外部情况来做出不同的响应,最直接的方法就是在程序中将这

Java设计模式系列之策略模式

策略模式的定义: 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换,策略模式让算法独立于使用它的客户而独立变化. 策略模式使这些算法在客户端调用它们的时候能够互不影响地变化. 策略模式的意义:   策略模式使开发人员能够开发出由许多可替换的部分组成的软件,并且各个部分之间是低耦合的关系. 低耦合的特性使软件具有更强的可扩展性,易于维护:更重要的是,它大大提高了软件的可重用性.    策略模式中有三个对象:      环境对象(Context):该类中实现了对抽象策略中

Java设计模式学习记录-状态模式

前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使用时无需关心对象的状态,可以实现自身的一致性处理.最近工作有些忙,更新博客慢了.还是要严格要求自己的,抽时间也要坚持学习. 状态模式 概念介绍 状态模式允许一个对象在其状态改变时,改变它的行为,对象看起来似乎修改了它的类. 想要在改变自身状态时改变对象行为,最直接的方法就是在代码中将所有可能发生的情

c#设计模式系列:状态模式(State pattern)

引言 我们在编程的时候,有时候会遇到,一个对象的行为动作会由对象的状态来决定的,也就是对象的行为是由状态来决定,如果对象的状态很多,那么也会由很多不同的行为,这时候我们一班会 if –else if-来判断对象的行为,当对象的行为或者状态发生变化时,就需要更改之前的代码,这样的设计就违背了开闭原则,而状态模式就是用来解决这样的问题的 状态模式的介绍 状态模式的定义 当一个对象的内在状态改变时允许改变其行为,这个对象看起来像改变了其类 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂

Java设计模式系列之迭代器模式

迭代器模式定义 迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示. 迭代器模式的角色构成 (1)迭代器角色(Iterator):定义遍历元素所需要的方法,一般来说会有这么三个方法:取得下一个元素的方法next(),判断是否遍历结束的方法hasNext()),移出当前对象的方法remove(), (2)具体迭代器角色(Concrete Iterator):实现迭代器接口中定义的方法,完成集合的迭代. (3)容器角色(Aggregate): 

Java设计模式系列之命令模式

命令模式(Command)的定义 将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化:对请求排队或记录日志,以及支持可撤销的操作,将”发出请求的对象”和”接收与执行这些请求的对象”分隔开来. 命令模式(Command)的适用性 1.抽象出待执行的动作以参数化某对象. 2.在不同的时刻指定.排列和执行请求. 3.支持取消操作. 4.支持修改日志,这样当系统崩溃时,这样修改可以被重做一遍. 5.用构建在原语操作上的高层操作构造一个系统. 命令模式(Command)的应用效果:1)comma

Java设计模式系列之桥接模式

桥接模式(Bridge)的定义 在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?这就要使用桥接模式 将抽象部分与它的实现部分分离,使它们都可以独立地变化. 桥接模式(Bridge)的动机 当一种抽象类型可能有多种实现方式时,一般情况我们可以考虑使用继承来解决抽象类型的多种实现,在抽象类型中定义接口,而子类负责接口的具体实现.但这种做法缺乏灵活性,由于抽象类型和子类之间紧紧地绑定在一起,使得这种关系在运行时不能再修改,这使得它难以修改.扩展和重用

Java 设计模式系列(九)组合模式

Java 设计模式系列(九)组合模式 将对象组合成树形结构以表示"部分-整体"的层次结构.组合模式使得用户对单个对象的使用具有一致性. 一.组合模式结构 Component: 抽象的组件对象,为组合中的对象声明接口,让客户端可以通过这个接口来访问和管理整个对象结构,可以在里面为定义的功能提供缺省的实现. Leaf: 叶子节点对象,定义和实现叶子对象的行为,不再包含其它的子节点对象. Composite: 组合对象,通常会存储子组件,定义包含子组件的那些组件的行为,并实现在组件接口中定义

Java 设计模式系列(二三)访问者模式(Vistor)

Java 设计模式系列(二三)访问者模式(Vistor) 访问者模式是对象的行为模式.访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变. 一.访问者模式结构 访问者模式适用于数据结构相对未定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化. 数据结构的每一个节点都可以接受一个访问者的调用,此节点向访问者对象传入节点对象,而访问者对象则反过来执行节点对象的操作.这样的过程叫做"双重分派