C++状态模式(State)

状态模式(State Pattern)是一种行为设计模式,它允许对象在内部状态改变时改变其行为。状态模式将状态的相关行为封装到独立的状态类中,并通过在这些状态类之间切换来改变对象的行为。这样可以使状态转换变得更加明确和易于管理。

实际应用场景

假设我们有一个简单的电梯控制系统。电梯可以处于不同的状态,例如停止、向上移动、向下移动。每种状态下,电梯的行为是不同的。我们可以使用状态模式来管理电梯的这些状态和行为。

代码示例

下面是一个使用状态模式实现电梯控制系统的示例代码:

1. 定义状态接口

首先,我们定义一个表示电梯状态的接口 ElevatorState,该接口包含电梯在不同状态下的行为方法。

#include <iostream>
#include <memory>

// 电梯状态接口
class ElevatorState {
public:
    virtual ~ElevatorState() = default;
    virtual void moveUp() = 0;
    virtual void moveDown() = 0;
    virtual void stop() = 0;
};

class ElevatorContext; // 前向声明
2. 定义具体状态类

然后,我们定义具体的状态类,例如 MovingUpStateMovingDownState 和 StoppedState,每个状态类实现 ElevatorState 接口。

class MovingUpState : public ElevatorState {
public:
    explicit MovingUpState(ElevatorContext* context) : context_(context) {}

    void moveUp() override {
        std::cout << "Already moving up." << std::endl;
    }

    void moveDown() override {
        std::cout << "Cannot move down while moving up." << std::endl;
    }

    void stop() override;

private:
    ElevatorContext* context_;
};

class MovingDownState : public ElevatorState {
public:
    explicit MovingDownState(ElevatorContext* context) : context_(context) {}

    void moveUp() override {
        std::cout << "Cannot move up while moving down." << std::endl;
    }

    void moveDown() override {
        std::cout << "Already moving down." << std::endl;
    }

    void stop() override;

private:
    ElevatorContext* context_;
};

class StoppedState : public ElevatorState {
public:
    explicit StoppedState(ElevatorContext* context) : context_(context) {}

    void moveUp() override;
    void moveDown() override;
    void stop() override {
        std::cout << "Already stopped." << std::endl;
    }

private:
    ElevatorContext* context_;
};
3. 定义电梯上下文类

接下来,我们定义一个电梯上下文类 ElevatorContext,它持有当前状态的实例,并提供改变状态的方法。

class ElevatorContext {
public:
    ElevatorContext() : state_(std::make_unique<StoppedState>(this)) {}

    void setState(std::unique_ptr<ElevatorState> state) {
        state_ = std::move(state);
    }

    void moveUp() {
        state_->moveUp();
    }

    void moveDown() {
        state_->moveDown();
    }

    void stop() {
        state_->stop();
    }

private:
    std::unique_ptr<ElevatorState> state_;
};
4. 实现状态转换

最后,我们在具体状态类中实现状态转换的方法。

void MovingUpState::stop() {
    std::cout << "Stopping from moving up." << std::endl;
    context_->setState(std::make_unique<StoppedState>(context_));
}

void MovingDownState::stop() {
    std::cout << "Stopping from moving down." << std::endl;
    context_->setState(std::make_unique<StoppedState>(context_));
}

void StoppedState::moveUp() {
    std::cout << "Starting to move up." << std::endl;
    context_->setState(std::make_unique<MovingUpState>(context_));
}

void StoppedState::moveDown() {
    std::cout << "Starting to move down." << std::endl;
    context_->setState(std::make_unique<MovingDownState>(context_));
}
5. 使用示例
int main() {
    ElevatorContext elevator;

    // 电梯从停止状态开始
    elevator.moveUp();    // 输出: Starting to move up.
    elevator.moveUp();    // 输出: Already moving up.
    elevator.stop();      // 输出: Stopping from moving up.
    elevator.moveDown();  // 输出: Starting to move down.
    elevator.stop();      // 输出: Stopping from moving down.
    elevator.moveDown();  // 输出: Starting to move down.

    return 0;
}

完整代码

#include <iostream>
#include <memory>

// 电梯状态接口
class ElevatorState {
public:
    virtual ~ElevatorState() = default;
    virtual void moveUp() = 0;
    virtual void moveDown() = 0;
    virtual void stop() = 0;
};
class ElevatorContext; // 前向声明

class MovingUpState : public ElevatorState {
public:
    explicit MovingUpState(ElevatorContext* context) : context_(context) {}

    void moveUp() override {
        std::cout << "Already moving up." << std::endl;
    }

    void moveDown() override {
        std::cout << "Cannot move down while moving up." << std::endl;
    }

    void stop() override;

private:
    ElevatorContext* context_;
};

class MovingDownState : public ElevatorState {
public:
    explicit MovingDownState(ElevatorContext* context) : context_(context) {}

    void moveUp() override {
        std::cout << "Cannot move up while moving down." << std::endl;
    }

    void moveDown() override {
        std::cout << "Already moving down." << std::endl;
    }

    void stop() override;

private:
    ElevatorContext* context_;
};

class StoppedState : public ElevatorState {
public:
    explicit StoppedState(ElevatorContext* context) : context_(context) {}

    void moveUp() override;
    void moveDown() override;
    void stop() override {
        std::cout << "Already stopped." << std::endl;
    }

private:
    ElevatorContext* context_;
};
class ElevatorContext {
public:
    ElevatorContext() : state_(std::make_unique<StoppedState>(this)) {}

    void setState(std::unique_ptr<ElevatorState> state) {
        state_ = std::move(state);
    }

    void moveUp() {
        state_->moveUp();
    }

    void moveDown() {
        state_->moveDown();
    }

    void stop() {
        state_->stop();
    }

private:
    std::unique_ptr<ElevatorState> state_;
};
void MovingUpState::stop() {
    std::cout << "Stopping from moving up." << std::endl;
    context_->setState(std::make_unique<StoppedState>(context_));
}

void MovingDownState::stop() {
    std::cout << "Stopping from moving down." << std::endl;
    context_->setState(std::make_unique<StoppedState>(context_));
}

void StoppedState::moveUp() {
    std::cout << "Starting to move up." << std::endl;
    context_->setState(std::make_unique<MovingUpState>(context_));
}

void StoppedState::moveDown() {
    std::cout << "Starting to move down." << std::endl;
    context_->setState(std::make_unique<MovingDownState>(context_));
}
int main() {
    ElevatorContext elevator;

    // 电梯从停止状态开始
    elevator.moveUp();    // 输出: Starting to move up.
    elevator.moveUp();    // 输出: Already moving up.
    elevator.stop();      // 输出: Stopping from moving up.
    elevator.moveDown();  // 输出: Starting to move down.
    elevator.stop();      // 输出: Stopping from moving down.
    elevator.moveDown();  // 输出: Starting to move down.

    return 0;
}

总结

在这个示例中,我们使用状态模式将电梯的不同状态(停止、向上移动、向下移动)封装到独立的状态类中。电梯上下文类 ElevatorContext 持有当前状态的实例,并通过调用状态对象的方法来改变电梯的行为和状态。这使得状态转换变得更加明确和易于管理,同时也提高了代码的可维护性和可扩展性。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
状态模式是一种行为设计模式,它允许通过改变对象的内部状态来改变对象的行为。状态模式主要解决了当控制一个对象状态转换的条件表达式过于复杂时的情况。通过将状态的判断逻辑转译到表现不同状态的一系列类中,可以简化复杂的判断逻辑。 在状态模式中,每个状态对应一个类,每个类管理一个状态。通过将对象在各种状态下的行为分离开,避免了使用if...else或switch...case分支结构,使程序结构简明化。这种设计方式不仅易于扩展,还简化了程序的维护和管理。 以C语言为例,可以使用枚举类型来定义各个状态,并使用条件语句来执行相应的行为。例如,在状态StateA时执行一些操作,在状态StateB时执行另一些操作。 总结来说,状态模式通过将对象的行为和状态分离,使程序结构更加清晰和易于扩展。它可以简化复杂的状态判断逻辑,提高代码的可读性和可维护性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [设计模式状态模式](https://blog.csdn.net/baidu_41388533/article/details/107787784)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [C++设计模式笔记——状态模式](https://blog.csdn.net/panjunnn/article/details/109532885)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值