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;
}
相关推荐
leo030820 小时前
7种流行Prompt设计模式详解:适用场景与最佳实践
设计模式·prompt
ytadpole1 天前
揭秘设计模式:工厂模式的五级进化之路
java·设计模式
烛阴1 天前
【TS 设计模式完全指南】用工厂方法模式打造你的“对象生产线”
javascript·设计模式·typescript
_请输入用户名1 天前
EventEmitter 是广播,Tapable 是流水线:聊聊它们的本质区别
前端·设计模式
Buling_01 天前
游戏中的设计模式——第一篇 设计模式简介
游戏·设计模式
小蜗牛在漫步1 天前
设计模式六大原则2-里氏替换原则
设计模式·里氏替换原则
小蜗牛在漫步1 天前
23种设计模式-Proxy模式
设计模式·代理模式
易元1 天前
模式组合应用-装饰器模式
后端·设计模式
宁静致远20211 天前
【C++设计模式】第二篇:策略模式(Strategy)--从基本介绍,内部原理、应用场景、使用方法,常见问题和解决方案进行深度解析
c++·设计模式·策略模式
CHANG_THE_WORLD1 天前
C++ 并发编程指南 并发设计模式:Actor vs. CSP (生活场景版)
c++·设计模式·生活