gpt4 book ai didi

c++ - 在状态模式上使用 'variation' - C++

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:58:26 28 4
gpt4 key购买 nike

概述:

我正在尝试改进我正在使用状态模式的程序的设计。我将发布问题的简要描述、当前设计的类图/描述的图像,然后是相关类的头代码。

问题:

我正在为程序使用状态模式的变体。在这个变体中,我有一个“ Controller ”,它使用两个抽象类,“状态”和“事件”,从这两个抽象类扩展了几个具体类型。这两个抽象类用于对根据事件类型和当前状态而变化的“事件”做出响应。每个状态都有一个“处理程序”函数,该函数被重载以获取每个具体事件类型。

“ Controller ”包含一个“事件”类型的队列(抽象类),其中包含已发生的“事件”(具体类)的列表。 Controller 一次“处理”每个事件,方法是从队列中检索事件,并将其传递给特定类型事件的状态处理程序。

问题在于,为了获得正确的类型以将事件传递给状态的适当处理程序,我必须将事件向下转换 为正确的具体类型。目前,我通过向类“状态”(getType()) 添加一个方法来完成此操作,该方法由每个具体事件类型实现,并返回一个表示该事件类型的整数。但是,这种做法非常“不优雅”,会导致使用枚举来驱动“开关” block 和“向下转型”——这不是很好的设计做法。

我怎样才能改变这个设计,使事件到状态的传递更优雅?

类图

Class diagram

标题代码

/*****
* CONTROLLER (driver) CLASS
*/
queue<event> events; //gets populated by other threads that hold reference to it
state* currentState;
vector<state*> allStates;
allStates.push_back( new state_1(&allStates) ); // passes reference to 'allStates' to each state
allStates.push_back( new state_2(&allStates) ); // so that it may return the 'next state'
...

while( true ){
event nextEvent;
state* nextState;
if( events.size() > 0 ){
nextEvent = events.front(); //Get next Event
events.pop(); //remove from queue
switch( nextEvent.getType() ){ //determine 'concrete type' based on 'getType method'
case 1:
//Downcast to concrete state type, and let state handle event
nextState = currentState->handle( *dynamic_cast<event_type_1*>(&nextEvent) );
break;
case 2:
state* nextState = currentState->handle( *dynamic_cast<event_type_1*>(&nextEvent) );
break;
...
}
//Transition to next state
currentState = nextState;
else
Sleep(5); //
}

/*****
* EVENT CLASSES
*/
class event{
public:
virtual int getType();
}

class event_type_1 : public event{
public:
int getType(){ return 1; };
int specializedFunc1();
double specializedFunc2();
}

class event_type_2 : public event{
public:
int getType(){ return 2; };
std::string specializedFunc3();
}

/*****
* STATE CLASSES
*/
class state{
protected:
vector<state*>* m_states;
public:
state( vector<state*>* p_states ){ m_states = p_states; };
virtual state* handle( event_type_1 );
virtual state* handle( event_type_2 );
}

class state_1 : public state{
public:
state* handle( event_type_1 );
state* handle( event_type_2 );
}

class state_2 : public state{
public:
state* handle( event_type_1 );
state* handle( event_type_2 );
}

最佳答案

添加一个抽象方法:

virtual state *transition(state *from) = 0;

参加事件。

然后在每个状态子类中实现如下:

state *transition(state *from)
{
from->handle(this);
}

然后在你的循环中调用:

nextState = nextEvent->transition(currentState);

编辑:

如果你使事件成为模板类的子类模板,你可以在事件类本身中实现转换:

template <class subclass> class event
{
state *transition(state *from)
{
from->handle(dynamic_cast<subclass *>(this));
}
}

关于c++ - 在状态模式上使用 'variation' - C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1572500/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com