Лучшее связывание двух подсистем на С++
От: Dr.Offset  
Дата: 04.05.08 12:32
Оценка:
Какой метд вы используете для связывания двух подсистем в своих программах?
После того, как я увидел в одной из библиотек подобное решение:
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();
        }
    }
};

Только, может я все усложняю? Если да, то какой, по-вашему, наиболее оптимальный способ связывания и взаимодействия разлиных подсистем в программе?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.