Система реализована так
Имеем абстрактный класс задачи
class TaskState;
class Task
{
public:
virtual TaskState * start(ObjectToControl * pObjectToControl) = 0;
friend class TaskState;
};
, класс менеджера последовательного выполнения задач,
class TaskManager
{
public:
...
void start()
{
update();
}
void update()
{
if(pCurTaskState != NULL)
{
pCurTaskState->update();
if(pCurTaskState->finished())
{
pCurTaskState = NULL;
Task * pNextTask = tasks.front();
pCurTaskState = pNextTask->start(pObjectToControl);
}
}
}
private:
TaskState * pCurTaskState;
ObjectToControl * pObjectToControl;
std::deque<Task*> tasks;
};
, абстрактный класс исполнителя задачи
class ObjectToControl
{
...
};
и абстрактный класс состояния выполнения задачи
class TaskState
{
public:
TaskState(Task * pTask_, ObjectToControl * pObjectToControl_) : pTask(pTask_), pObjectToControl(pObjectToControl_) {;}
...
virtual void update() //переопределяется реализациями
{
if(pTask->checkFinishCondition()) //условия останова, не зависящие от состояния выполнения задачи
{
finished = true;
}
}
bool finished() const { return finished; }
...
private:
Task * pTask;
ObjectToControl * pObjectToControl;
bool finished;
};
.
-Task — задача с параметрами как таковая. Неизменна.
-Конкретные реализации Task задачи имеют свой набор параметров и умеют порождать конкретные реализации TaskState, передавая им ObjectToControl.
-TaskState — состояние выполнения конкретной задачи, конкретным исполнителем. Класс меняет свое состояние через TaskState::update().
-Выполнение задачи может закончиться — TaskState::finished().
template<class TaskClass>
class ConcreteTaskState : public TaskState
{
public:
ConcreteTaskState(TaskClass * pTypedTask__, ObjectToControl * pObjectToControl_) : TaskState(pObjectToControl_, pTypedTask),
pTypedTask(pTypedTask_) {;}
private:
TaskClass * pTypedTask;
}
-Реализации TaskState должны иметь широкий интерфейс (через friend class) к реализации породившей их задачи, поэтому нужен шаблонный ConcreteTaskState. Реализации Task порождают только реализации шаблонного класса ConcreteTaskState.
-С другой стороны реализации Task могут породить разные реализации (варианты) ConсreteTaskState.
Собственно вопрос, насколько всё это красиво и правильно? Изначально хотел сделать TaskState наследником Task чтобы упростить доступ из TaskState к параметрам в Task, потом передумал, решив что это сущности разной природы. Стоило ли здесь использовать наследование и можно ли эту систему написать более изящно?