如何建立网站或网页,大连网龙网络科技有限公司,如何建设好医院网站,嘉兴网站建设全包在C设计模式中#xff0c;状态模式#xff08;State Pattern#xff09;是一种行为设计模式#xff0c;它允许对象在内部状态改变时改变其行为#xff0c;使对象看起来似乎修改了其类。状态模式的主要动机、意图和适用场合如下#xff1a;
动机
在面向对象的设计中设计模式中状态模式State Pattern是一种行为设计模式它允许对象在内部状态改变时改变其行为使对象看起来似乎修改了其类。状态模式的主要动机、意图和适用场合如下
动机
在面向对象的设计中对象的行为往往依赖于其状态。传统的实现方式是在对象中使用大量的条件语句来检查状态并执行相应的操作。这种做法有以下几个问题
代码复杂性随着状态的增多条件语句会变得越来越复杂难以维护。可扩展性差添加新状态时需要修改现有的条件语句违反了开闭原则对扩展开放对修改关闭。状态转移不清晰状态之间的转移逻辑分散在各个地方不便于管理和理解。
为了解决这些问题状态模式应运而生。
意图
状态模式的意图是将对象的状态抽象成类层次结构并将行为封装在这些状态类中。具体来说
定义一个状态接口该接口声明了所有可能状态共有的操作。为每种状态实现一个具体的类每个类都实现了状态接口中的操作并在必要时处理状态转换。维护一个当前状态的引用主体对象通过这个引用委托给当前状态对象执行相应的操作。
通过这种方式状态模式将状态相关的逻辑从主体类中分离出来使得代码更加清晰、模块化并且易于扩展。
适用场景
状态模式适用于以下情况
对象行为依赖于其状态且需要根据状态改变行为。状态之间有复杂的转移逻辑需要明确地定义状态转换规则。希望将状态相关的代码集中管理提高代码的可维护性和可扩展性。需要对不同的状态进行不同的操作并且这些操作可能涉及复杂的业务逻辑。
例如一个自动售货机可以根据其当前状态如待支付、已支付、缺货等执行不同的操作如接收硬币、发放商品、退还余额等。使用状态模式可以清晰地定义每种状态下的行为以及状态之间的转换。
示例代码
以下是一个简单的C示例展示了状态模式的使用
#include iostream
#include memory// 状态接口
class State {
public:virtual void handle(const std::string input) 0;virtual ~State() default;
};// 具体状态A
class StateA : public State {
public:void handle(const std::string input) override {std::cout StateA handles: input std::endl;// 可能会转换到其他状态}
};// 具体状态B
class StateB : public State {
public:void handle(const std::string input) override {std::cout StateB handles: input std::endl;// 可能会转换到其他状态}
};// 主体类
class Context {
public:void setState(std::shared_ptrState state) {currentState state;}void request(const std::string input) {if (currentState) {currentState-handle(input);}}
private:std::shared_ptrState currentState;
};int main() {// 创建具体状态实例auto stateA std::make_sharedStateA();auto stateB std::make_sharedStateB();// 创建上下文并设置初始状态Context context;context.setState(stateA);// 处理请求context.request(Initial request);// 转换状态context.setState(stateB);context.request(Another request);return 0;
}在这个示例中Context 类维护了一个 State 接口的指针并将处理请求委托给当前状态对象。不同的状态类 (StateA 和 StateB) 实现了不同的处理逻辑。通过设置不同的状态Context 对象可以表现出不同的行为。
通过这种方式状态模式使得状态相关的逻辑更加清晰和模块化同时也便于添加新的状态而不需要修改现有的代码。 面是一个使用状态模式来模拟Windows PnPPlug and Play设备驱动中状态转移的C示例。我们将定义一个设备驱动类和多个状态类每个状态类将处理不同状态下的设备行为和状态转移。
状态模式在PnP设备驱动中的应用
定义状态接口定义一个状态接口 State声明所有可能状态共有的操作。实现具体状态类为每种状态如 Unplugged、PlugIn、Initialize、Ready实现一个具体的类。维护当前状态在 DeviceDriver 类中维护一个当前状态的引用并根据需要切换状态。
示例代码
#include iostream
#include memory
#include string// 状态接口
class State {
public:virtual ~State() default;virtual void onUnplug(DeviceDriver* driver) 0;virtual void onPlugIn(DeviceDriver* driver) 0;virtual void onInitialize(DeviceDriver* driver) 0;virtual void onReady(DeviceDriver* driver) 0;
};// 设备驱动类
class DeviceDriver {
public:DeviceDriver() : currentState(std::make_sharedUnplugged()) {}void unplug() {currentState-onUnplug(this);}void plugIn() {currentState-onPlugIn(this);}void initialize() {currentState-onInitialize(this);}void ready() {currentState-onReady(this);}void setState(const std::shared_ptrState state) {currentState state;}private:std::shared_ptrState currentState;
};// 具体状态未插入
class Unplugged : public State {
public:void onUnplug(DeviceDriver* driver) override {std::cout Already unplugged. std::endl;}void onPlugIn(DeviceDriver* driver) override {std::cout Device plugged in. std::endl;driver-setState(std::make_sharedPlugIn());}void onInitialize(DeviceDriver* driver) override {std::cout Cannot initialize. Device not plugged in. std::endl;}void onReady(DeviceDriver* driver) override {std::cout Cannot be ready. Device not plugged in. std::endl;}
};// 具体状态已插入
class PlugIn : public State {
public:void onUnplug(DeviceDriver* driver) override {std::cout Device unplugged. std::endl;driver-setState(std::make_sharedUnplugged());}void onPlugIn(DeviceDriver* driver) override {std::cout Already plugged in. std::endl;}void onInitialize(DeviceDriver* driver) override {std::cout Device initialized. std::endl;driver-setState(std::make_sharedInitialize());}void onReady(DeviceDriver* driver) override {std::cout Cannot be ready. Device not initialized. std::endl;}
};// 具体状态已初始化
class Initialize : public State {
public:void onUnplug(DeviceDriver* driver) override {std::cout Device unplugged. std::endl;driver-setState(std::make_sharedUnplugged());}void onPlugIn(DeviceDriver* driver) override {std::cout Already plugged in and initialized. std::endl;}void onInitialize(DeviceDriver* driver) override {std::cout Already initialized. std::endl;}void onReady(DeviceDriver* driver) override {std::cout Device is ready to use. std::endl;driver-setState(std::make_sharedReady());}
};// 具体状态已准备好
class Ready : public State {
public:void onUnplug(DeviceDriver* driver) override {std::cout Device unplugged. std::endl;driver-setState(std::make_sharedUnplugged());}void onPlugIn(DeviceDriver* driver) override {std::cout Device is already ready. std::endl;}void onInitialize(DeviceDriver* driver) override {std::cout Device is already initialized and ready. std::endl;}void onReady(DeviceDriver* driver) override {std::cout Device is already ready. std::endl;}
};int main() {DeviceDriver driver;// 模拟设备插拔和状态转移driver.plugIn();driver.initialize();driver.ready();driver.unplug();driver.plugIn();driver.ready();return 0;
}代码说明 状态接口 State 定义了四个虚函数onUnplug、onPlugIn、onInitialize、onReady分别对应设备在不同状态下的行为。 设备驱动类 DeviceDriver 维护一个当前状态 currentState并提供四个公共方法 unplug、plugIn、initialize、ready这些方法委托给当前状态对象处理。提供 setState 方法用于切换状态。 具体状态类 Unplugged设备未插入状态。PlugIn设备已插入状态。Initialize设备已初始化状态。Ready设备已准备好状态。 主函数 main 创建一个 DeviceDriver 对象并模拟设备的插拔和状态转移过程。
通过这种方式状态模式使得设备驱动的代码更加模块化和可维护状态之间的转换也更加清晰 状态模式通常与其他设计模式协同使用以提高代码的模块化和可维护性。以下是状态模式常见的协同模式及其使用场景
1. 策略模式 (Strategy Pattern)
场景当不同状态下的行为可以通过不同的算法实现时可以使用策略模式来定义这些算法。协同方式状态模式中的每个状态类可以包含一个策略对象用于实现具体的行为。这样状态的改变不仅涉及状态的切换还可以动态改变算法。示例在状态模式中不同状态下的设备初始化可以使用不同的初始化策略。
2. 工厂模式 (Factory Pattern)
场景当状态类的创建需要复杂逻辑时可以使用工厂模式来创建状态对象。协同方式通过工厂模式可以在状态切换时动态创建所需的状态对象而不需要在每个地方重复创建逻辑。示例使用工厂模式创建设备驱动的初始状态或特定状态。
3. 观察者模式 (Observer Pattern)
场景当状态变化需要通知其他对象时可以使用观察者模式。协同方式状态对象可以充当被观察者其他对象如日志记录器、UI 更新器等可以注册为观察者当状态变化时观察者会收到通知并作出相应处理。示例在设备驱动状态变化时通知UI更新显示状态。
4. 单例模式 (Singleton Pattern)
场景当状态类需要全局唯一实例时可以使用单例模式。协同方式状态类可以通过单例模式确保每个状态在整个应用中只有一个实例这有助于节省资源并确保状态的一致性。示例确保设备的“未插入”状态在整个应用中只有一个实例。
5. 模板方法模式 (Template Method Pattern)
场景当状态类有共同的骨架方法但具体实现不同步时可以使用模板方法模式。协同方式状态类可以定义一个模板方法该方法包含一系列步骤其中某些步骤的具体实现由具体的子类提供。示例定义一个模板方法 handleEvent该方法包含一系列步骤如检查前置条件、执行操作、更新状态等具体状态类可以覆盖这些步骤的实现。
6. 命令模式 (Command Pattern)
场景当状态变化需要记录或撤销时可以使用命令模式。协同方式每个状态变化可以封装成一个命令对象命令对象可以记录状态变化的操作便于撤回或重做。示例记录设备状态变化的命令以便在需要时恢复到之前的状态。
7. 责任链模式 (Chain of Responsibility Pattern)
场景当状态变化需要多个对象处理时可以使用责任链模式。协同方式状态变化可以传递给一个链中的多个对象每个对象根据其职责处理或传递请求。示例当设备状态变化时多个处理器如日志记录器、安全检查器等可以顺序处理该状态变化。
示例
以下是一个结合状态模式和工厂模式、策略模式的示例
#include iostream
#include memory
#include string// 策略接口
class InitializationStrategy {
public:virtual void initialize() 0;virtual ~InitializationStrategy() default;
};// 具体策略快速初始化
class QuickInitialization : public InitializationStrategy {
public:void initialize() override {std::cout Quick initialization std::endl;}
};// 具体策略完整初始化
class FullInitialization : public InitializationStrategy {
public:void initialize() override {std::cout Full initialization std::endl;}
};// 状态接口
class State {
public:virtual ~State() default;virtual void onUnplug(DeviceDriver* driver) 0;virtual void onPlugIn(DeviceDriver* driver) 0;virtual void onInitialize(DeviceDriver* driver) 0;virtual void onReady(DeviceDriver* driver) 0;
};// 状态工厂类
class StateFactory {
public:static std::shared_ptrState createUnpluggedState() {return std::make_sharedUnplugged();}static std::shared_ptrState createPlugInState() {return std::make_sharedPlugIn();}static std::shared_ptrState createInitializeState() {return std::make_sharedInitialize();}static std::shared_ptrState createReadyState() {return std::make_sharedReady();}
};// 设备驱动类
class DeviceDriver {
public:DeviceDriver() : currentState(StateFactory::createUnpluggedState()) {}void unplug() {currentState-onUnplug(this);}void plugIn() {currentState-onPlugIn(this);}void initialize() {currentState-onInitialize(this);}void ready() {currentState-onReady(this);}void setState(const std::shared_ptrState state) {currentState state;}private:std::shared_ptrState currentState;
};// 具体状态未插入
class Unplugged : public State {
public:void onUnplug(DeviceDriver* driver) override {std::cout Already unplugged. std::endl;}void onPlugIn(DeviceDriver* driver) override {std::cout Device plugged in. std::endl;driver-setState(StateFactory::createPlugInState());}void onInitialize(DeviceDriver* driver) override {std::cout Cannot initialize. Device not plugged in. std::endl;}void onReady(DeviceDriver* driver) override {std::cout Cannot be ready. Device not plugged in. std::endl;}
};// 具体状态已插入
class PlugIn : public State {
public:PlugIn() : strategy(std::make_uniqueQuickInitialization()) {}void onUnplug(DeviceDriver* driver) override {std::cout Device unplugged. std::endl;driver-setState(StateFactory::createUnpluggedState());}void onPlugIn(DeviceDriver* driver) override {std::cout Already plugged in. std::endl;}void onInitialize(DeviceDriver* driver) override {std::cout Device initialized. std::endl;strategy-initialize();driver-setState(StateFactory::createInitializeState());}void onReady(DeviceDriver* driver) override {std::cout Cannot be ready. Device not initialized. std::endl;}private:std::unique_ptrInitializationStrategy strategy;
};// 具体状态已初始化
class Initialize : public State {
public:void onUnplug(DeviceDriver* driver) override {std::cout Device unplugged. std::endl;driver-setState(StateFactory::createUnpluggedState());}void onPlugIn(DeviceDriver* driver) override {std::cout Already plugged in and initialized. std::endl;}void onInitialize(DeviceDriver* driver) override {std::cout Already initialized. std::endl;}void onReady(DeviceDriver* driver) override {std::cout Device is ready to use. std::endl;driver-setState(StateFactory::createReadyState());}
};// 具体状态已准备好
class Ready : public State {
public:void onUnplug(DeviceDriver* driver) override {std::cout Device unplugged. std::endl;driver-setState(StateFactory::createUnpluggedState());}void onPlugIn(DeviceDriver* driver) override {std::cout Device is already ready. std::endl;}void onInitialize(DeviceDriver* driver) override {std::cout Device is already initialized and ready. std::endl;}void onReady(DeviceDriver* driver) override {std::cout Device is already ready. std::endl;}
};int main() {DeviceDriver driver;// 模拟设备插拔和状态转移driver.plugIn();driver.initialize();driver.ready();driver.unplug();driver.plugIn();driver.ready();return 0;
}代码说明 策略接口 InitializationStrategy 定义了一个初始化策略接口包含一个 initialize 方法。具体策略类 QuickInitialization 和 FullInitialization 实现了不同的初始化策略。 状态工厂类 StateFactory 提供静态方法创建不同状态的实例。 具体状态类 PlugIn 包含一个策略对象 strategy在 onInitialize 方法中使用该策略进行初始化。 主函数 main 创建一个 DeviceDriver 对象并模拟设备的插拔和状态转移过程。
通过这种方式状态模式与工厂模式和策略模式协同使用使得代码更加灵活和可维护。