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

简介: 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。 状态模式的角色 1. 环境角色Context):也称上下文,定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。

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

状态模式的角色
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. 设计模式读书笔记—–状态模式

目录
相关文章
|
5月前
|
设计模式 网络协议 Java
【设计模式】【行为型模式】状态模式(State)
一、入门 什么是状态模式? 状态模式(State Pattern)是一种行为设计模式,允许对象在其内部状态改变时改变其行为,使其看起来像是改变了类。状态模式的核心思想是将对象的状态封装成独立的类,并将
232 16
|
8月前
|
设计模式 Java Go
【再谈设计模式】状态模式~对象行为的状态驱动者
状态模式属于行为型设计模式。它将对象的行为封装在不同的状态类中,使得对象在不同的状态下表现出不同的行为。上下文(Context):这是一个包含状态对象的类,它定义了客户感兴趣的接口,并维护一个具体状态对象的引用。上下文将操作委托给当前的状态对象来处理。抽象状态(State):这是一个抽象类或者接口,它定义了一个特定状态下的行为接口。所有具体的状态类都实现这个接口。具体状态(Concrete State):这些是实现抽象状态接口的类,每个具体状态类实现了与该状态相关的行为。
227 18
|
设计模式 网络协议 Java
【十五】设计模式~~~行为型模式~~~状态模式(Java)
文章详细介绍了状态模式(State Pattern),这是一种对象行为型模式,用于处理对象在其内部状态改变时的行为变化。文中通过案例分析,如银行账户状态管理和屏幕放大镜工具,展示了状态模式的应用场景和设计方法。文章阐述了状态模式的动机、定义、结构、优点、缺点以及适用情况,并提供了Java代码实现和测试结果。状态模式通过将对象的状态和行为封装在独立的状态类中,提高了系统的可扩展性和可维护性。
【十五】设计模式~~~行为型模式~~~状态模式(Java)
|
设计模式 Java 测试技术
Java设计模式-状态模式(18)
Java设计模式-状态模式(18)
141 0
|
设计模式 JavaScript Go
js设计模式【详解】—— 状态模式
js设计模式【详解】—— 状态模式
267 7
|
设计模式 Go
[设计模式 Go实现] 行为型~状态模式
[设计模式 Go实现] 行为型~状态模式
131 3
|
设计模式
状态模式-大话设计模式
状态模式-大话设计模式
101 0
|
设计模式 存储
行为设计模式之状态模式
行为设计模式之状态模式
|
设计模式 JavaScript Java
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
166 0
|
设计模式 Java
【设计模式系列笔记】状态模式
在Java中,状态模式是一种行为设计模式,它允许对象在其内部状态改变时改变其行为。状态模式的关键思想是将对象的状态封装成独立的类,并将对象的行为委托给当前状态的对象。这样,当对象的状态发生变化时,其行为也会相应地发生变化。
222 0