[英]How to determine states for the State pattern
我正在开发一个 DLL,用于通过 LAN 控制 POS(销售点)终端。
DLL 提供了执行操作的命令,例如:
DLL 还提供了 Connect() 和 Disconnect() 函数。
由于 POS 终端可以处于各种状态,我认为状态模式可能会在 DLL 中使用。
伪代码:
// My DLL
class Pos
{
public:
Pos();
~Pos();
bool Connect();
bool Disconnect();
bool DoLogon() { m_pCurrentPosState->DoLogon(this); }
bool DoLogoff() { m_pCurrentPosState->DoLogoff(this); }
bool DoAuthorisation() { m_pCurrentPosState->DoAuthorisation(this); }
bool DoReadCardData() { m_pCurrentPosState->DoReadCardData(this); }
bool DoCancellation() { m_pCurrentPosState->DoCancellation(this); }
bool DoRefund() { m_pCurrentPosState->DoRefund(this); }
bool DoNetworkDiagnosis() { m_pCurrentPosState->DoNetworkDiagnosis(this); }
...
private:
void ChangeState(PosState *pPosState) { m_pCurrentPosState = pPosState; }
private:
friend class PosState;
PosState *m_pCurrentPosState;
...
};
class PosState
{
public:
// Implement default behavior for all command requests.
virtual bool DoLogon(Pos *pPos) {}
virtual bool DoLogoff(Pos *pPos) {}
virtual bool DoAuthorisation(Pos *pPos) {}
virtual bool DoReadCardData(Pos *pPos) {}
virtual bool DoCancellation(Pos *pPos) {}
virtual bool DoRefund(Pos *pPos) {}
virtual bool DoNetworkDiagnosis(Pos *pPos) {}
protected:
void ChangeState(Pos *pPos, PosState *pPosState);
};
class PosLoggedon : public PosState
{
public:
static PosState* Instance();
// Implement state-specific behavior.
bool DoLogoff(Pos *pPos);
bool DoAuthorisation(Pos *pPos);
bool DoReadCardData(Pos *pPos);
bool DoCancellation(Pos *pPos);
bool DoRefund(Pos *pPos);
bool DoNetworkDiagnosis(Pos *pPos);
};
class PosLoggedoff : public PosState
{
public:
static PosState* Instance();
// Implement state-specific behavior.
bool DoLogon(Pos *pPos);
bool DoAuthorisation(Pos *pPos);
bool DoReadCardData(Pos *pPos);
bool DoCancellation(Pos *pPos);
bool DoRefund(Pos *pPos);
bool DoNetworkDiagnosis(Pos *pPos);
};
PosLoggedon和PosLoggedoff都是我认为有效的两种状态,但我不确定如何确定其他状态。
创建PosAuthorisation 、 PosReadCardData等状态以便它们对应于 POS 功能是否有意义? 大概没意思吧...
我对如何正确使用状态模式感到困惑,因为我混合了“当前正在进行的命令”和“当前的 POS 状态”。
也许我需要像PosCommandInProgress这样的状态?
任何意见,将不胜感激。
非常感谢。
状态通常是用动词来描述的。 例如, parsing
听起来像是一种状态。 UserLogged
听起来不像是一种状态,它听起来更像是一个可以改变状态的事件。
如果你想要一个状态机,你需要确定哪些动作涉及不同的状态,哪些不涉及。 例如,可以有一个waiting for input
的状态。 每次用户需要做某事时,机器就会进入这种状态。 可能不需要做很多状态,比如waiting for address input
, waiting for name input
等等,因为它们实际上都是在waiting for input
状态。
现在,在每个州都有两件事。 首先是状态机在该状态下可以做的事情的列表。 例如,如果是等待用户输入自己的名字,在waiting for input
状态下,可以显示可爱小猫的图片,但是绝对不能对用户的银行账户进行操作。
第二件事是机器在当前状态期间可以改变的状态列表。 例如,它可以从waiting for input
状态更改为showing the greeting message
。
所以,不要用命令的混合状态。 命令可以在状态中执行,命令可以导致机器改变它的状态,但它们并不相同。
如果您的 DLL 可以
Logon Logoff Authorisation Read card data Cancellation Refund Network diagnosis
那么你可能会有connecting
、 waiting for authorization information input
、 authorizing
、 waiting for account operation choice
、 executing account operation
、 logging off
。
所以在connecting
你可能需要运行网络诊断来检查是否可以连接,然后建立连接,获取服务器响应,显示一些 UI 以请求用户数据,并切换到waiting for authorization information
状态,然后做其他事情, 等等。
希望有帮助。
通常在代码中实现真实世界的范式反射是好的。 如果您:
大多数硬件模块被实现为状态机。 状态模式很容易理解,所以你不太可能有维护问题
我认为你会特别喜欢重新实现不适用的虚拟成员以在没有if (state == XX) ... else if (state == YY) ...
:)
一些非代码例如:
interface AbstractBeing
{
void sleep();
void eat();
void lieDownAndDie();
};
class ImAlive implements AbstractBeing
{
void sleep() {doZzzzzzz();}
void eat() {nomNomNomNom();}
void lieDownAndDie() {turnUndead();}
};
class ImUndead implements AbstractBeing
{
void sleep() {throw error("zombies aint need no sleep");}
void eat() {seekBrainzzzz();}
void lieDownAndDie() {throw error("no you!!");}
};
希望这可以帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.