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;
}
相关推荐
触底反弹38 分钟前
🤯 面试被问 AI Workflow 和 Agent 有啥区别?3 张图 + 2 段代码讲清楚!
人工智能·设计模式·面试
杨充21 小时前
10.可测试性实战设计
设计模式·开源·代码规范
杨充21 小时前
9.重构十二式的实战
设计模式·开源·代码规范
杨充21 小时前
6.设计原则的全景图
设计模式·开源·全栈
杨充21 小时前
2.面向对象的特性
设计模式
杨充21 小时前
7.SOLID原则案例汇
设计模式·开源·全栈
杨充21 小时前
8.反模式与坏味道
设计模式·开源·代码规范
杨充21 小时前
3.接口vs抽象类比较
设计模式
咖啡八杯1 天前
文法、BNF与AST
java·设计模式·解释器模式·ast·文法