设计模式:状态模式(State)

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

状态模式的角色

1. 环境角色Context):也称上下文,定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。

2. 抽象状态角色(State):定义一个接口,用以封装环境对象的一个特定的状态所对应的行为。

3. 具体状态角色(ConcreteState):每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。

案例

以酒店订房为例,房间的状态有:空闲、预订、入住。那么空闲房间的状态可以转变为:预订、入住。已预订状态房间的状态可以转变为:入住、取消预订。已入住房间的状态可以转变为:退房

1 状态接口State

public interface State
{
    public void bookRoom();
    public void unsubscribeRoom();
    public void checkInRoom();
    public void checkOutRoom();
}

2 房间类Room(环境角色)

public class Room
{
    private State freeTimeState;
    private State checkInState;
    private State bookedState;

    private State state;

    public Room()
    {
        freeTimeState = new FreeTimeState(this);
        checkInState = new CheckInState(this);
        bookedState = new BookedState(this);
        state = freeTimeState;
    }

    public void bookRoom()
    {
        state.bookRoom();
    }
    public void unsubscribeRoom()
    {
        state.unsubscribeRoom();
    }
    public void checkInRoom()
    {
        state.checkInRoom();
    }
    public void checkOutRoom()
    {
        state.checkOutRoom();
    }

    public String toString()
    {
        return "该房间的状态是:"+getState().getClass().getName();
    }

    public State getFreeTimeState()
    {
        return freeTimeState;
    }

    public void setFreeTimeState(State freeTimeState)
    {
        this.freeTimeState = freeTimeState;
    }

    public State getCheckInState()
    {
        return checkInState;
    }

    public void setCheckInState(State checkInState)
    {
        this.checkInState = checkInState;
    }

    public State getBookedState()
    {
        return bookedState;
    }

    public void setBookedState(State bookedState)
    {
        this.bookedState = bookedState;
    }

    public State getState()
    {
        return state;
    }

    public void setState(State state)
    {
        this.state = state;
    }
}

3 房间状态(具体状态角色)

空闲状态

public class FreeTimeState implements State
{
    private Room hotelManagement;

    public FreeTimeState(Room hotelManagement)
    {
        this.hotelManagement = hotelManagement;
    }
    @Override
    public void bookRoom()
    {
        System.out.println("您已经预定成功了!");
        this.hotelManagement.setState(this.hotelManagement.getBookedState());
    }

    @Override
    public void unsubscribeRoom()
    {
    }

    @Override
    public void checkInRoom()
    {
        System.out.println("您已经入住了!");
        this.hotelManagement.setState(this.hotelManagement.getCheckInState());
    }

    @Override
    public void checkOutRoom()
    {
    }
}

入住状态

public class CheckInState implements State
{
    private Room hotelManagement;

    public CheckInState(Room hotelManagement)
    {
        this.hotelManagement = hotelManagement;
    }
    @Override
    public void bookRoom()
    {
        System.out.println("该房间已经入住了");
    }

    @Override
    public void unsubscribeRoom()
    {
    }

    @Override
    public void checkInRoom()
    {
        System.out.println("该房间已经入住了");
    }

    @Override
    public void checkOutRoom()
    {
        System.out.println("退房成功");
        this.hotelManagement.setState(this.hotelManagement.getFreeTimeState());
    }
}

预订状态

public class BookedState implements State
{
    private Room hotelManagement;

    public BookedState(Room hotelManagement)
    {
        this.hotelManagement = hotelManagement;
    }

    @Override
    public void bookRoom()
    {
        System.out.println("该房间已经预定了");
    }

    @Override
    public void unsubscribeRoom()
    {
        System.out.println("成功退订");
        this.hotelManagement.setState(this.hotelManagement.getFreeTimeState());
    }

    @Override
    public void checkInRoom()
    {
        System.out.println("入住成功");
        this.hotelManagement.setState(this.hotelManagement.getCheckInState());
    }

    @Override
    public void checkOutRoom()
    {
    }
}

4 测试代码

        Room[] rooms = new Room[2];
        for(int i=0;i<rooms.length;i++)
        {
            rooms[i] = new Room();
        }

        rooms[0].bookRoom();
        rooms[0].checkInRoom();
        rooms[0].bookRoom();
        System.out.println(rooms[0]);
        System.out.println("-------------");

        rooms[1].checkInRoom();
        rooms[1].bookRoom();
        rooms[1].checkOutRoom();
        rooms[1].bookRoom();
        System.out.println(rooms[1]);

输出:

您已经预定成功了!
入住成功
该房间已经入住了
该房间的状态是:design.state.CheckInState
-------------
您已经入住了!
该房间已经入住了
退房成功
您已经预定成功了!
该房间的状态是:design.state.BookedState


优缺点

优点:

1. 封装了转换规则。

2. 枚举可能的状态,在枚举状态之前需要确定状态种类。

3. 将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。

4. 允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。

缺点:

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

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

3. 状态模式对“开闭原则”的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码。

适用场景

1. 对象的行为依赖于它的状态(属性)并且可以根据它的状态而改变它的相关行为

2. 代码中包含大量与对象状态相关的条件语句

JDK中的状态模式:

java.util.Iterator

javax.faces.lifecycle.LifeCycle#execute()



参考资料

1. 23种设计模式

2. 细数JDK里的设计模式

3. 设计模式读书笔记—–状态模式

时间: 2024-08-30 12:04:36

设计模式:状态模式(State)的相关文章

设计模式 - 状态模式(state pattern) 未使用状态模式 详解

状态模式(state pattern) 未使用状态模式 详解 本文地址: http://blog.csdn.net/caroline_wendy 状态模式可以控制状态的转换, 未使用设计模式时, 程序会非常繁杂. 具体方法: 1. 状态转换类. /** * @time 2014年7月11日 */ package state; /** * @author C.L.Wang * */ public class GumballMachine { final static int SOLD_OUT =

设计模式 - 状态模式(state pattern) 详解

状态模式(state pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy 状态模式(state pattern): 允许对象在内部状态改变时改变它的行为, 对象看起来好像修改了它的类. 建立Context类, 包含多个具体状态(concrete state)类的组合, 根据状态的不同调用具体的方法, state.handle(), 包含set\get方法改变状态. 状态接口(state interface), 包含抽象方法handle(),

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

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

深入浅出设计模式——状态模式(State Pattern)

模式动机 在很多情况下,一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做状态,这样的对象叫做有状态的 (stateful)对象,这样的对象状态是从事先定义好的一系列值中取出的.当一个这样的对象与外部事件产生互动时,其内部状态就会改变,从而使得系统的行为也随之发生变化.在UML中可以使用状态图来描述对象状态的变化. 模式定义状态模式(State Pattern) :允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类.其别名为状态对象(Objects for Stat

设计模式 状态模式 以自动售货机为例

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/26350617 状态模式给了我眼前一亮的感觉啊,值得学习~ 先看定义:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类.定义又开始模糊了,理一下,当对象的内部状态改变时,它的行为跟随状态的改变而改变了,看起来好像重新初始化了一个类似的. 下面使用个例子来说明状态模式的用法,现在有个自动售货机的代码需要我们来写,状态图如下: 分析一个这个状态图: a.包含4个状态(

14. 星际争霸之php设计模式--状态模式

题记==============================================================================本php设计模式专辑来源于博客(jymoz.com),现在已经访问不了了,这一系列文章是我找了很久才找到完整的,感谢作者jymoz的辛苦付出哦! 本文地址:http://www.cnblogs.com/davidhhuan/p/4248198.html============================================

【C#设计模式-状态模式】

一.状态模式的定义:状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况.把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化. 二.状态模式的意图:允许一个对象在其内部状态改变时改变它的行为. 三.状态模式的适用场景: 1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为. 2.一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态. 四.状态模式的实现: /// <summary> /// 定义接口,封装Context对象在特定

JAVA 设计模式 状态模式

用途 状态模式 (State) 当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 状态模式是一种行为型模式. 结构 图-状态模式结构图 State : 定义一个接口以封装与 Context 的一个特定状态相关的行为. abstract class State {    public abstract void Handle(Context context);} ConcreteState : 每一个子类实现一个与 Context 的一个状态相关的行为. class Con

状态模式 State

状态模式(State),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. Context中有成员变量标志其状态,在每次请求过后,在具体状态类中设置其变化至的类. // State.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> #include <string> using names

设计模式-状态模式(State Pattern)

本文由@呆代待殆原创,转载请注明出处:http://www.cnblogs.com/coffeeSS/ 状态模式简介 状态模式允许一个对象在其内部状态改变的时候改变它的行为,他的内部会存着好几种状态,在当前状态发生变化是,这个对象执行和之前相同的操作也会有不同的作用效果. 状态模式的定义和基本结构 定义:状态模式允许一个对象在其内部状态改变的时候改变它的行为,就像变成了另一个对象一样. 一张来自<Head First>的结构图 Context:这个类里面包含了很多种状态类,当前状态不同时,这个