状态模式通过将对象的状态封装为独立类,使对象在状态改变时能改变行为。Context(如Door类)持有当前状态的引用,并将状态相关操作委托给状态对象处理;State定义状态行为的接口,ConcreteState(如ClosedState)实现具体行为及状态转换逻辑。该模式用多态替代冗长的条件判断,提升代码可维护性与扩展性,符合开闭原则。尽管会增加类的数量,但在状态复杂、转换频繁的场景下优势明显。示例中门的三种状态(关闭、打开、上锁)各自封装,状态切换由具体状态类控制,使逻辑清晰且易于扩展。
C++中的状态模式(State Pattern)是一种行为型设计模式,它允许对象在内部状态改变时改变其行为,从而让对象看起来像是改变了它的类。简单来说,就是把特定状态下的行为逻辑封装到独立的状态类中,让主对象(上下文)把具体的行为委托给当前状态对象来执行。
当我第一次接触状态模式时,老实说,我觉得它有点“绕”,毕竟多了一堆类。但当你真的面对一个复杂对象,它的行为会因为内部状态不同而天差地别,而且这些状态还会频繁切换时,你就会发现它的魅力了。核心思想很简单:把每一种状态都抽象成一个独立的类,然后让主对象(我们称之为Context)在运行时持有当前状态的一个引用。当Context需要执行某个操作时,它就把这个操作委托给它当前持有的状态对象去处理。
通常,实现上会包含这几个角色:
- Context(上下文): 这是拥有状态的对象。它会维护一个指向当前具体状态对象的引用,并把所有与状态相关的请求都委托给这个当前状态对象处理。Context本身通常不包含太多状态相关的业务逻辑,它的职责更像是“调度员”。
- State(抽象状态): 定义一个接口,封装与Context的特定状态相关的行为。所有的具体状态类都将实现这个接口。
- ConcreteState(具体状态): 实现State接口,为Context的每一个特定状态提供具体的行为。这些类还会负责处理状态转换的逻辑,比如,一个
OpenState
在接收到
close()
请求后,可能会将Context的状态设置为
ClosedState
。
这个模式的优点,在我看来,最显著的就是它极大地提升了代码的可维护性和可扩展性。你想想看,如果不用状态模式,我们可能要在Context里写一大堆
if-else
或者
语句来判断当前是什么状态,然后执行对应的逻辑。一旦状态增多,或者某个状态的行为逻辑改变,那简直就是一场灾难,牵一发而动全身。但有了状态模式,每个状态的逻辑都封装在自己的类里,互不干扰。新增一个状态?好办,加个新类就行,Context几乎不用改,这不就是开闭原则的体现嘛。
立即学习“C++免费学习笔记(深入)”;
当然,它也不是万能药,最明显的代价就是类的数量会增加。如果你的状态机非常简单,比如只有两三个状态,且状态转换逻辑固定,那可能用
if-else
反而更直接。但一旦复杂起来,状态模式的优势就显而易见了。
举个例子,我们来模拟一个简单的门,它有“关闭”、“打开”和“上锁”三种状态。
#include <iostream> #include <string> #include <memory> // For std::shared_ptr // Forward declaration class Door; // 抽象状态接口 class DoorState { public: virtual ~DoorState() = default; virtual void open(Door* door) = 0; virtual void close(Door* door) = 0; virtual void lock(Door* door) = 0; virtual void unlock(Door* door) = 0; virtual std::string getStateName() const = 0; }; // 上下文类 class Door { private: std::shared_ptr<DoorState> currentState; public: Door(); // Constructor will set initial state void setState(std::shared_ptr<DoorState> newState) { currentState = newState; std::cout << "门状态变为: " << currentState->getStateName() << std::endl; } void open() { currentState->open(this); } void close() { currentState->close(this); } void lock() { currentState->lock(this); } void unlock() { currentState->unlock(this); } std::string getCurrentStateName() const { return currentState->getStateName(); } }; // 具体状态类 class ClosedState : public DoorState
评论(已关闭)
评论已关闭