我正在开发一个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);
};PosLoggedoff和PosLoggedon都是我认为有效的两种状态,但我不知道如何确定其他状态。
创建像PosAuthorisation,PosReadCardData这样的状态以使它们与POS函数相对应是否有意义?也许这没有道理..。
我对如何正确使用State模式感到困惑,因为我将“当前命令正在进行”和“当前POS状态”混为一谈。
也许我需要一个像PosCommandInProgress这样的状态
如有任何建议,将不胜感激。
非常感谢。
发布于 2012-07-31 09:58:11
状态通常是用动词描述的事物。例如,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可以
登录注销授权读卡数据取消退款网络诊断
然后你可能会有像connecting,waiting for authorization information input,authorizing,waiting for account operation choice,executing account operation,logging off这样的州。
因此,在connecting中,您可能需要运行网络诊断来检查是否可以进行连接,然后建立连接,获取服务器响应,显示一些UI以请求用户数据,切换到waiting for authorization information状态,然后再做其他事情,等等。
希望这能有所帮助。
发布于 2012-07-31 10:08:15
通常,在代码中实现真实世界的范例反射是很好的。国家是非常适当的,如果你:
大多数硬件模块都是作为状态机实现的。状态模式很容易理解,因此您不太可能出现维护问题。
我认为您特别喜欢重新实现不适用的虚拟成员,在没有if (state == XX) ... else if (state == YY) ...的情况下抛出错误:)
例如,一些非a代码:
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!!");}
};霍普,这有帮助
https://stackoverflow.com/questions/11737107
复制相似问题