8. 状态模式

目录

一、应用背景

  • 某对象发生变化时,其所能做的操作也随之变化。
  • 应用程序的可维护性和重用性差
  • 代码的逻辑较复杂

二、状态模式

2.1 解决的问题

  • 允许一个对象在其内部状态改变时改变化的行为

2.2 角色

  • 环境类(Context):客户使用的对象料。维护一个State子类的实例,这个实例定义当前状态
  • 抽象状态类(State):定义一个抽象以封装瑟Context的一个特定状态相关的行为
  • 具体状态类(ConcreteState):每一子类实现一个与Context的一个状态相关的行为

2.3 实现步骤

  • 定义抽象状态类,实现当前系统的真实状态继承自此抽象状态类
  • 定义Context类,具有状态的类,其中包含抽象状态类的对象
  • 定义具体状态类,实现当前系统的真实状态类
    • 当Context类执行某个接口的方法时,去调用真实状态类的实现方法
    • 当Context类修改状态时,修改Context类的真实状态对象

三、通用设计类图

  • Context:上下文/环境类,即状态的拥有者
  • State:抽取出的抽象状态类,里面规定了该类拥有的行
  • Concrete StateA:具体的状态类

四、实现

  • 设置酒店房间管理功能

4.1 设计类图

  • 房间类:环境类,状态拥有者
  • 房间状态类:抽象类,定义房间的状态信息
  • xxx状态类:各种不同的房间状态信息,继承自房间状态类

4.2 状态转换图

4.3 代码实现

cpp 复制代码
#include <iostream>

class Room;

class State
{
public:
    virtual std::string getState() = 0;
    virtual void book(Room* room) = 0;
    virtual void checkin(Room* room) = 0;
    virtual void unbook(Room* room) = 0;
    virtual void checkout(Room* room) = 0;
};

class Room
{
protected:
    State* s;

public:
    std::string getState()
    {
        return s->getState();
    }

    void setState(State* a)
    {
        s = a;
    }

    void book()
    {
        s->book(this);
    }

    void checkin()
    {
        s->checkin(this);
    }

    void unbook()
    {
        s->unbook(this);
    }

    void checkout()
    {
        s->checkout(this);
    }
};

class FreeState : public State
{
public:
    std::string getState() override
    {
        return "当前为空闲状态";
    }

    void book(Room* room) override;

    void checkin(Room* room) override;

    void unbook(Room* room) override
    {
        std::cout << "当前为空闲状态,无法进行取消预定操作" << std::endl;
    }

    void checkout(Room* room) override
    {
        std::cout << "当前为空闲状态,无法进行退房操作" << std::endl;
    }
};

class BookState : public State
{
public:
    std::string getState() override
    {
        return "当前为预定状态";
    }

    void book(Room* room) override
    {
        std::cout << "当前已经是预定状态,无须重复预订" << std::endl;
    }

    void checkin(Room* room) override;

    void unbook(Room* room) override;

    void checkout(Room* room) override
    {
        std::cout << "当前是预定状态,无须退房" << std::endl;
    }
};

class CheckinState : public State
{
public:
    std::string getState() override
    {
        return "当前为入住状态";
    }

    void book(Room* room) override
    {
        std::cout << "当前是入住状态,无法预定" << std::endl;
    }

    void checkin(Room* room) override
    {
        std::cout << "当前是入住状态,无须重复入住" << std::endl;
    }

    void unbook(Room* room) override
    {
        std::cout << "当前是入住状态,无法取消预定" << std::endl;
    }

    void checkout(Room* room) override
    {
        std::cout << "退房操作" << std::endl;
        room->setState(new FreeState());
    }
};

void FreeState::book(Room* room)
{
    std::cout << "预订操作" << std::endl;
    room->setState(new BookState());
}

void FreeState::checkin(Room* room)
{
    std::cout << "入住操作" << std::endl;
    room->setState(new CheckinState());
}

void BookState::checkin(Room* room)
{
    std::cout << "入住操作" << std::endl;
    room->setState(new CheckinState());
}

void BookState::unbook(Room* room)
{
    std::cout << "取消预订操作" << std::endl;
    room->setState(new FreeState());
}

int main()
{
    Room* r = new Room();
    State* s = new FreeState();
    r->setState(s);

    std::cout << "=============================" << std::endl;
    std::cout << r->getState() << std::endl;

    std::cout << "=============================" << std::endl;
    r->checkin();
    std::cout << r->getState() << std::endl;

    std::cout << "=============================" << std::endl;
    r->checkout();
    r->book();
    r->checkout();
    std::cout << r->getState() << std::endl;

    return 0;
}
相关推荐
lincats7 小时前
大白话讲解Addy Osmani 的循环工程Loop Engineering工作流
人工智能·驱动开发·架构·prompt·状态模式·知识图谱
码匠许师傅11 小时前
【设计模式精讲】15.享元模式(Flyweight)
c++·设计模式·享元模式·uml
事圆则缓11 小时前
Android 常用设计模式速查
android·设计模式
MetaLite12 小时前
Java通用枚举驱动下拉框-元数据接口与前端契约
java·前端·状态模式
码匠许师傅1 天前
【设计模式精讲】14.外观模式(Facade)
c++·设计模式·uml·外观模式
evans在进步1 天前
Java 常用设计模式(二):装饰器、适配器、责任链、模板方法、策略与观察者
java·开发语言·设计模式
骑士雄师1 天前
HITL = Human-in-the-Loop(人在回路中)
状态模式
码匠许师傅1 天前
【设计模式精讲】13.装饰器模式(Decorator)
c++·设计模式·uml·装饰器模式
星恒随风1 天前
C++11详解(一):统一初始化——列表初始化与 initializer_list
c++·笔记·学习·list·状态模式
许彰午2 天前
22-DataCenter报文序列化
java·低代码·架构·状态模式