Реализация шаблона состояния с помощью структуры данных Graph
В настоящее время я пытаюсь реализовать приложение, где есть около 10 государств. В отличие от традиционного шаблона состояний, когда существует только 1 ссылка на другое состояние из одного состояния, я хочу, чтобы он был больше похож на ориентированный граф, в котором одно состояние может иметь несколько ребер для разных состояний.
Пример: у меня есть состояния 1-10 (вершины). - это края. Это могут быть возможные переходы состояний.
1-2, 1-3, 1-6 2-3, 2-9 3-5 4-3 5-2, 5-3, 5-4 6-3, 6-4,6-7, 6-9... И так далее
Каждое состояние - это классы, а каждое ребро (-) - это методы. Например:
Class State1 {
public void goToState2() ;
public void goToState3() ;
public void goToState6() ;
}
Class State2 {
public void goToState3() ;
public void goToState9() ;
}
...
Я мог бы подумать об отражении и куче операторов switch для решения этой проблемы, но я думаю, что я мог бы также применить шаблон состояний или придумать более элегантное решение, но я абсолютно застрял.
Любая помощь или руководство будут оценены!
0 ответов
Поскольку задействован граф переходов между состояниями, необходимо поддерживать смежность и определять критерии перехода. Этот критерий может быть общим для всех узлов (например, переход от одного узла к другому продиктован стоимостью перехода) или его можно настроить для каждого узла (например, на одном узле переход происходит на основе стоимости, в то время как для другого переход происходит на основе узла тип).
class ExecutionParameters;
class IState;
using SPState = std::shared_ptr<IState>;
using SPStates = std::list<SPState>;
class _declspec(novtable) IState
{
public:
virtual void Execute(Context& context, const ExecutionParameters& params) = 0;
virtual SPStates GetAdjacentStates() const noexcept = 0;
};
class _declspec(novtable) ITransitionCriteria
{
public:
virtual SPState ComputeNextState() const = 0;
};
class CostBasedTransition : public ITransitionCriteria
{
public:
SPState ComputeNextState() const override
{
// Find min transition cost adjacent node
}
};
using SPTransitionCriteria = std::shared_ptr<ITransitionCriteria>;
class StateNode : public IState
{
public:
StateNode(int id, SPTransitionCriteria spTransitionCriteria) :m_id(id), m_spTransitionCriteria(spTransitionCriteria)
{}
StateNode(int id) :StateNode(id, nullptr)//Choose default transition criteria//)
{}
void Execute(Context& context, const ExecutionParameters& params) override
{
// Perform action
// Update context state
context.SetState(m_spTransitionCriteria->GetNextState());
}
SPStates GetAdjacentStates() const noexcept
{
return m_spAdjacentStates;
}
void AddAjacentState(SPState spState)
{
}
void RemoveAjacentState(int stateId)
{
}
private:
int m_id;
SPStates m_spAdjacentStates;
SPTransitionCriteria m_spTransitionCriteria;
};
class Context
{
public:
void Execute(const ExecutionParameters& params)
{
m_spState->Execute(*this, params);
}
void SetState(SPState& spState)
{
m_spState = spState;
}
private:
SPState m_spState;
};