Какой метд вы используете для связывания двух подсистем в своих программах?
После того, как я увидел в одной из библиотек подобное решение:
class graphic
{
public:
action * data; // указатель на данные связанные с графическим объектом.
};
мне стало понятно, что выбрать правильный путь здесь довольно нелегко. Ибо вышеприведенное решение может и не отличается красотой, зато обеспечивает приемлемое быстродействие. Это намного эффективнее, чем, скажем std::map<graphic*, action*>, но и нарушает инкапсуляцию. Ведь по сути графичесое представление не должно ничего знать о данных.
У себя я использую вот такую схему:
namespace view // графичесая подсистема
{
class graphic
{
public:
virtual void draw() const = 0;
};
class graphic_rect : public graphic
{
public:
void draw() const;
};
}
namespace activity // Данные
{
class action
{
public:
virtual void data() const = 0;
};
class action_rect : public action
{
public:
void data() const;
};
}
После такого разбиения, на подсистемы, при необходимости организовать их взаимодействие как раз и возникает проблема сабжа. Я решил вести 3ю небольшую подсистему, чтобы объединить их логически.
class substance // просто означает, что такой объект существует.
{
public:
virtual activity::action * action() = 0;
virtual view::graphic * graphic() = 0;
};
class rect_substance : public substance, // "сущность" обьекта "прямоугольник" =)
private activity::action_rect,
private view::graphic_rect
{
public:
activity::action_rect * action() // доступ к данным (не графическим) прямоугольника
{
return this;
}
view::graphic_rect * graphic() // доступ к графической подсистеме
{
return this;
}
};
Учитывая это, необходимо представить работу контроллера и графического контроллера этих подсистем. В связи с вышеизложенным они примут вид.
class graphic_engine
{
std::list<substance*> & _GraphicObjs; // ссылка на список в контроллере
public:
graphic_engine(std::list<substance*> & __graphicObjs)
: _GraphicObjs(__graphicObjs)
{}
/*
в методах с графикой работаем по типу _GraphicObjs.front()->graphic()->draw();
*/
void paint();
// возвращает указатель на объект, графическое представление которого имеет координаты x,y
substance * select(int x, int y);
};
class controller
{
std::list<substance*> _Objs;
graphic_engine _GEngine;
public:
controller()
: _GEngine(_Objs)
{}
void something_job()
{
substance * s = _GEngine.select(3, 4);
if(s) // объект найден, работаем с данными
{
s->action()->data();
}
}
};
Только, может я все усложняю? Если да, то какой, по-вашему, наиболее оптимальный способ связывания и взаимодействия разлиных подсистем в программе?
Здравствуйте, Dr.Offset, Вы писали:
DO>Только, может я все усложняю? Если да, то какой, по-вашему, наиболее оптимальный способ связывания и взаимодействия разлиных подсистем в программе?
наиболее оптимальный зависит от задачи ИМХО.
Я незнаю как вы владеете ООП\ООД но то что было описано выше напоминает Модель- представление — контроллер.
В данном контексте я бы тоже его использовал
. И на мой взгляд такая структура не усложняет а наоборот способствует пониманию программы.
http://www.rsdn.ru/Forum/?mid=581850Автор: Варвар
Дата: 25.03.04
Вот почитай если ты об этом.
Здравствуйте, lollipop, Вы писали:
L>Я незнаю как вы владеете ООП\ООД но то что было описано выше напоминает Модель- представление — контроллер.
L> В данном контексте я бы тоже его использовал . И на мой взгляд такая структура не усложняет а наоборот способствует пониманию программы.
Нет, я немножко не об этом. Да, я тут использовал эту модель, но лишь для демонстрации. Я немного более узкий вопрос хотел задать. В самом начале я привел пример, когда указатель на данные содержится непосредственно в классе графического представления. То есть, такая архитектура преполагает знание одной системы о другой. А потом я довольно развернуто попытался объяснить альтернативу, которую я использую, что бы этого избежать, основанную на множественном наследовании. Здесь есть еще третий способ, использование которого, я встречал иногда в некоторых проектах — это храниение пар по типу std::pair<graphic*, action*>.
Я интересовался у уважаемой общественности, есть ли еще какие-либо эффективные методы, которыми возможно заменить мою реализацию (или ее исправить\дополнить), или, например, которые выгодно использовать в каких-то других случаях =)
Здравствуйте, Dr.Offset, Вы писали:
DO>Здравствуйте, lollipop, Вы писали:
L>>Я незнаю как вы владеете ООП\ООД но то что было описано выше напоминает Модель- представление — контроллер.
L>> В данном контексте я бы тоже его использовал . И на мой взгляд такая структура не усложняет а наоборот способствует пониманию программы.
DO>Нет, я немножко не об этом. Да, я тут использовал эту модель, но лишь для демонстрации. Я немного более узкий вопрос хотел задать. В самом начале я привел пример, когда указатель на данные содержится непосредственно в классе графического представления. То есть, такая архитектура преполагает знание одной системы о другой. А потом я довольно развернуто попытался объяснить альтернативу, которую я использую, что бы этого избежать, основанную на множественном наследовании. Здесь есть еще третий способ, использование которого, я встречал иногда в некоторых проектах — это храниение пар по типу std::pair<graphic*, action*>.
DO>Я интересовался у уважаемой общественности, есть ли еще какие-либо эффективные методы, которыми возможно заменить мою реализацию (или ее исправить\дополнить), или, например, которые выгодно использовать в каких-то других случаях =)
std::pair<graphic*, action*>. — так обычно в паттерне Фабрика делают. (что то , указатель на коллбэк функцию).
Я обычно пользуюсь паттерном комманд. Либо фабрикой. Примеры есть в Loki