「设计模式」 状态模式
背景:类的行为是随着它的状态改变的而改变
问题:分支语句实现的程序可维护性差、重用性差;代码逻辑复杂
定义:允许对象在其内部状态改变时改变它的行为。
使用环境:
一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。
一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。
角色:上下文、状态
实现:环境类、抽象状态类、状态类
缺点:
类爆炸;
违反了开闭原则;what why 鱼和熊掌不可兼得
new - delete 耗时,且可能造成内存碎片(参考);对象内存计算
状态过于分散,逻辑不够清晰;优点即缺点
结构和实现略复杂;
优点:
解决了多层分支语句;
分离状态实现,状态扩展性好;
特点:状态转移的逻辑不在分支语句中,而是在State子类中。
思考:
状态转换操作放在环境类中,还是状态子类中?
放在子类中的缺点是,增加了子类之间的依赖关系;
注意:new 之后的对象不使用的话一定要delete,否则会造成内存泄漏;
状态和策略的区别是什么?
(逻辑)状态模式中的子类(状态)之间具有相互转换的关系,而策略模式中,子类之间是平等可相互替换的关系;
(场景)状态和策略所面对的环境及其实现完全不同;
(核心功能区分主次)策略模式的核心在于子类的实现,环境类只充当了子类算法选择的功能,该模式侧重点在于子类;而状态模式,其核心在于环境类,状态子类只是为了简化逻辑控制,做的辅助操作;
(解决了分支结构)状态模式真正解决了分支结构,而策略只是转移了分支结构;why
设计原则
目录
if (“空闲” == state)
{
if ("预订" == operate)
{
预订操作;
state = "已预订";
}
else if ("入住" == operate)
{
入住操作;
state = "已入住";
}
}
else if (“已预订” == state)
{
if ("入住" == operate)
{
入住操作;
state = "已入住";
}
else if ("取消预订" == operate)
{
取消预订操作;
state = "空闲";
}
}
下面的情形用状态模式合适吗?
文档视图:页面视图、大纲视图、web视图、预览;×
状态之间具有相互转换的关系,但是此处,各状态更接近于切换的关系;
状态模式的产生,源于状态之间相互转换时,影响了对象的行为,而文档视图切换时,并未明显影响到文档的核心行为,相反,只是显示格式做了改变,核心编辑功能也只存在可使用与不可使用两种状态;
Room.h头文件
class Room:public State {
public:
void SetState(State* pState);
void Book();
void Unbook();
void Checkin();
void Checkout();
private:
State* m_cpState;
};
Room.cpp源文件
#include “Room.h”
void Room::SetState(State* pState) {
m_cpState = pState;
}
void Room::Book() {
m_cpState->Book();delete m_cpState;
m_cpState = new Reserved();
}
void Room::Unbook() {
m_cpState->Unbook();
m_cpState = new FreeState();
}
void Room::Checkin() {
m_cpState->Checkin();
m_cpState = new CheckIn();
}
void Room::Checkout() {
m_cpState->Checkout();
m_cpState = new FreeState();
}
State.h头文件
class State {
public:
virtual void Book() = 0;
virtual void Unbook() = 0;
virtual void Checkin() = 0;
virtual void Checkout() = 0;
};
子类 头文件
class Reserved : public State {
public:
void Book();
void Unbook();
void Checkin();
void Checkout();
};
子类 源文件
void Free::Book() {//具体实现}
void Free::Checkin() {//具体实现}
void Free::Unbook() {//空}
void Free::Checkout() {//空}
Comments