Составной объект
От: fryme  
Дата: 08.04.11 09:12
Оценка:
Никак не получается гармонично описать достаточно простой интерфейс.
Суть такая: есть некая сущность, которая выполняет задания (Task). Задания могут быть разных типов, всего предположим, что 5 типов заданий (SuperTask, PuperTask etc.) у каждого своя специфика, свои методы исполнения и т.п. Я сделал базовый класс Task и от него просто пронаследовал все эти специфические типы заданий, просто переопределив в каждом метод run() по-своему.
У всех заданий есть общие характеристики, параметры и прочее, которые хранятся в БД. В какой то момент задания грузятся из БД, динамически по полю типа (поле в БД) определяется что за задание и заполняется массив вроде: tasks.push_back( TaskFactory::create ( sqlResult.type)).
Затем сущность, которая управляет всеми этими задачами начинает их исполнять: tasks.last()->run().
До этого момента всё понятно.

Но встал вопрос, что нужно сделать сделать некий тип задачи, данные для которого всё так же берутся из БД, но при этом он получается как бы составной (CompositeTask), т.е. в его методе run() нужно будет использовать разные другие методы других заданий. Поясню:

class Task {
    public:
        // Метод запускающий выполнение задачи
        virtual void run() = 0;
        
        // Данные из БД лежат тут
        struct _DBStructure {
            ...
            std::string field;
            ...
        } DBStructure;
};


class SuperTask : public Task {
    public:
        // У каджого своё
        void run() { 
            //
        }
};

class PuperTask : public Task {
    public:
        // У каджого своё
        void run() {
        }
};


class CompositeTask : public Task {
    public:
        void run() {
            SuperTask sTask;
            sTask.DBStructure.field = DBStructure.field;
            sTask.run();
            
            PuperTask pTask;
            pTask.DBStructure.field = DBStructure.field;
            pTask.run();
            
            SuperTask sTask2;
            sTask2.DBStructure.field = DBStructure.field;
            sTask2.run();
            
            // и тд последовательность из много разных методов
        }
};




Вот не понимаю как организовать структуру так, чтобы было так сказать красиво. Момент с копированием полей из CompositeTask.DBStructure мне кажутся очень кривым. Кто прочитал и понял о чём речь может посоветовать что то по делу?
Заранее спасибо!
c++
Re: Составной объект
От: goldblueranger  
Дата: 08.04.11 11:20
Оценка:
F>Вот не понимаю как организовать структуру так, чтобы было так сказать красиво. Момент с копированием полей из CompositeTask.DBStructure мне кажутся очень кривым. Кто прочитал и понял о чём речь может посоветовать что то по делу?

Чтобы красиво нужен массив Task* в CompositeTask и делать то что вы деалете полиморфно, в цикле.
Re[2]: Составной объект
От: fryme  
Дата: 08.04.11 12:13
Оценка:
Здравствуйте, goldblueranger, Вы писали:

F>>Вот не понимаю как организовать структуру так, чтобы было так сказать красиво. Момент с копированием полей из CompositeTask.DBStructure мне кажутся очень кривым. Кто прочитал и понял о чём речь может посоветовать что то по делу?


G>Чтобы красиво нужен массив Task* в CompositeTask и делать то что вы деалете полиморфно, в цикле.


Т.е. вот так:

typedef std::vector <Task *> Tasks;
Tasks tasksForCompositeTask;
tasksForCompositeTask.push_back(new SuperTask);
...


void CompositeTask :: run() {

Tasks::iterator it_beg = tasksForCompositeTask.begin();
while(it_beg != tasksForCompositeTask.end()) {
(*it_beg)->run();
it_beg++;
}
}

Но получается, что в цикле всёравно перед run() надо каждому заданию выставлять параметры, а так чтоб не выставлять, можно?
Они же впринципе есть уже у CompositeTask.DBStructure.
Re[3]: Составной объект
От: stenkil  
Дата: 08.04.11 13:29
Оценка:
Здравствуйте, fryme, Вы писали:

F>Но получается, что в цикле всёравно перед run() надо каждому заданию выставлять параметры, а так чтоб не выставлять, можно?

F>Они же впринципе есть уже у CompositeTask.DBStructure.

А почему в метод run нельзя передать указатель на параметры?
Re: Составной объект
От: Буравчик Россия  
Дата: 08.04.11 16:24
Оценка:
Здравствуйте, fryme, Вы писали:

F>Никак не получается гармонично описать достаточно простой интерфейс.


Может быть так?

class CompositeTask : public Task {
    public:
        void run() {
            SuperTask sTask;
            runTask(sTask);
            
            PuperTask pTask;
            runTask(pTask);
                            
            SuperTask sTask2;
            runTask(sTask2);
            
            // и тд последовательность из много разных методов
        }
        
        void runTask(Task task) {
            task.DBStructure.field = DBStructure.field;
            task.run();
        }
}


Правда, мне это не очень нравится.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Best regards, Буравчик
Re: Составной объект
От: AlexNek  
Дата: 08.04.11 21:26
Оценка:
Здравствуйте, fryme, Вы писали:

f> Никак не получается гармонично описать достаточно простой интерфейс.

....
Незнаю насколько красиво, но таск должен быть аналогом трее ноде и в конструктор каждого таска передается указатель на ВСЕ данные или ноль.

Типа этого добавить (синтакс "чисто теоретический")

Task rootTask = new Task1();
rootTask.Run();
....
protected virtual Task.OnDataReady(Data data)
{
   InitChildren(data);
   taskQueue.Run();
}

protected override Task1.InitChildren(Data data)
{
  Task subTask;
  subTask = new Task11(data);
  Add (subTask);
  subTask = new Task12(data);
  Add (subTask);
....
}
avalon 1.0rc3 rev 380, zlib 1.2.3
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.