Russian Qt Forum
Май 07, 2024, 01:27 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 ... 5   Вниз
  Печать  
Автор Тема: Вопрос по архитектуре приложения. Медиатор  (Прочитано 34402 раз)
nata267
Гость
« : Июнь 07, 2012, 15:00 »

Взято из QtDesigner.

Как в приложении реализовать доступ к любому компоненту системы из любого компонента системы, не
связывая компоненты напрямую друг с другом. Реализуется с помощью паттерна "Медиатор". Вот нашла реализацию в одном проекте.

Интерфейс медиатора. Операторы копирования и присваивания медиатора в секции private
Код:
class MediatorInterface : public QObject
{
    Q_OBJECT

public:

    MediatorInterface(QObject *parent = 0);
    virtual ~MediatorInterface();

    
    ComponentOneInterface *componentOne() const;
    ComponentTwoInterface *componentTwo() const;
    ComponentThreeInterface *componentThree() const;


    void setComponentOne(ComponentOneInterface *componentOne);
    void setComponentTwo(ComponentTwoInterface *componentTwo);
    
protected:
    void setComponentThree(ComponentThreeInterface *componentThree);

private:
    MediatorInterfacePrivate *d;

private:
    MediatorInterface(const MediatorInterface &other);
    void operator = (const MediatorInterface &other);
};

//конструктор
MediatorInterface::MediatorInterface(QObject *parent)
    : QObject(parent),
      d(new MediatorInterfacePrivate())
{
}

//деструктор
MediatorInterface::~MediatorInterface()
{
    delete d;
}

//возвращает интерфейс компонента
ComponentOneInterface *MediatorInterface::componentOne() const
{
    return d->m_componentOne;
}

//устанавливает компонент
void MediatorInterface::setComponentOne(ComponentOneInterface *componentOne)
{
    d->m_componentOne = componentOne;
}

Инкапсуляция указателей (не знаю можно ли так выразится). Или это опять какой-то шаблон???
Код:
class MediatorInterfacePrivate {

public:
    MediatorInterfacePrivate();
    ~MediatorInterfacePrivate();


    QPointer<ComponentOneInterface> m_componentOne;
    QPointer<ComponentTwoInterface> m_componentTwo;
    QPointer<ComponentThreeInterface> m_componentThree;
    
};

//конструктор
MediatorInterfacePrivate::MediatorInterfacePrivate() :
    m_componentOne(0),
    m_componentTwo(0),
    m_componentThree(0)
{
}

//деструктор
MediatorInterfacePrivate::~MediatorInterfacePrivate()
{
    delete m_componentOne;
    delete m_componentTwo;
    delete m_componentThree;
}


Конккретный медиатор проекта
Код:
class Mediator : public MediatorInterface
{
    Q_OBJECT

public:
    Mediator(QObject *parent = 0);
    virtual ~Mediator();
};


Mediator::Mediator(QObject *parent)
    : MediatorInterface(parent)
{

    ComponentThree *componentThree = new ComponentThree(this);
    setComponentThree(componentThree);
    ............
    создание компонентов чья функция set находится в секции protected
}

Указатель на медиатора передается в конструктор компонента.

Код:
class ComponentOne: public ComponentOneInterface
{
    Q_OBJECT

public:
    ComponentOne(MediatorInterface *core, QObject *parent = 0);
    virtual ~ComponentOne();

    .....
}
« Последнее редактирование: Июнь 19, 2012, 12:02 от nata267 » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Июнь 07, 2012, 17:13 »

Как в приложении реализовать доступ к любому компоненту системы из любого компонента системы, не
связывая компоненты напрямую друг с другом. Реализуется с помощью паттерна "Медиатор". Вот нашла реализацию в одном проекте.
Ну так в чем вопрос-то? Да, я узнал что есть паттерн "медиатор" который что-то делает. Если Вы считаете что нужно его использовать в Вашей задаче - ну Вам виднее. Но темы для обсуждения не видно  Улыбающийся

Ладно, "архитектура" - это реально трудно, попробую поддержать хороший почин. Я читаю Вику, но не особо усердно и не очень верю в прочитанное. Вряд ли кому-то нужен доступ "любого к любому", это выглядит прожектерством. Неясно чем же медиатор выигрывает по сравнению с незатейливым наследованием. Ведь смысл как-то пользоваться полученным (вызывать методы). Пример из жизни сделал бы обсуждение более продуктивным, пока дубль-пусто  Улыбающийся
Записан
alexis031182
Гость
« Ответ #2 : Июнь 07, 2012, 17:26 »

Хорошая тема. Насколько я помню, медиатор нужен для обеспечения двунаправленной связи между объектами. В варианте с наследованием приходится сохранять ссылки друг на друга. Медиатор должен работать по принципу "один ко многим". Связанные объекты ничего не знают друг о друге, в то время как медиатор знает обо всех.
Записан
nata267
Гость
« Ответ #3 : Июнь 07, 2012, 17:56 »

Пример из жизни сделал бы обсуждение более продуктивным, пока дубль-пусто  Улыбающийся

Этот пример как раз взят из реального проекта, а именно редактора форм QDesigner. Я переименовала классы для наглядности. В проекте QDesigner компонентами системы выступают:  QExtensionManager(менеджер дополнений), QDesignerPropertyEditorInterface(интерфейс окна редактора свойств объектов), QDesignerObjectInspectorInterface(интерфейс инспектора объектов), QDesignerActionEditorInterface(интерфейс окна редактора Аctions), а также QDesignerPluginManager, QtResourceModel, QDesignerSettingsInterface и многие другие компоненты системы
Моему классу MediatorInterface соответствует класс QDesignerFormEditorInterface.
Записан
nata267
Гость
« Ответ #4 : Июнь 07, 2012, 18:23 »

Приведу пример как в методах компонентов используется указатель на медиатора. Компонентом выступает ActionEditor - окно редактора Actions

Код:
class ActionEditor: public QDesignerActionEditorInterface
{
    Q_OBJECT
public:
    explicit ActionEditor(QDesignerFormEditorInterface *core, QWidget *parent = 0, Qt::WindowFlags flags = 0);
    virtual ~ActionEditor();
....

интерфейс которого:

Код:
class QDesignerActionEditorInterface: public QWidget
{
    Q_OBJECT
public:
    QDesignerActionEditorInterface(QWidget *parent, Qt::WindowFlags flags = 0);
    virtual ~QDesignerActionEditorInterface();

    virtual QDesignerFormEditorInterface *core() const;
...........
};


QDesignerFormEditorInterface *core - указатель на медиатора

вот отрывки из методов  ActionEditor в которых используется указатель на медиатора. В первом методе мы обращаемся к компоненту настроек, для восстановления настроек окна, во втором обращаемся к компоненту QDesignerPropertySheetExtension. Это компонент дополнения связаного как-то со свойствами объектов, может быть с их хранением и чтением, пока ещё не разобралась:

Код:
void ActionEditor::restoreSettings()
{
    QDesignerSettingsInterface *settings = m_core->settingsManager();
    m_actionView->setViewMode(settings->value(QLatin1String(actionEditorViewModeKey), 0).toInt());
    updateViewModeActions();
}
...
void ActionEditor::manageAction(QAction *action)
{
    .....
    core()->metaDataBase()->add(action);

   .......

    QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), action);
    sheet->setChanged(sheet->indexOf(QLatin1String(objectNamePropertyC)), true);
    sheet->setChanged(sheet->indexOf(QLatin1String(textPropertyC)), true);
    refreshIconPropertyChanged(action, sheet);

   ...............
}
« Последнее редактирование: Июнь 07, 2012, 18:42 от nata267 » Записан
alexis031182
Гость
« Ответ #5 : Июнь 07, 2012, 18:29 »

Оно конечно хорошо, но если речь о концепции, то лучше, наверное, пример взять поближе к простым смертным, на вроде меня. Обосновано ли использование медиатора в случае, если требуется взаимодействие, например, объектов файлов и объектов групп владельцев этих файлов между собой? Естественно, что один файл может быть доступен нескольким группам владельцев. Или достаточно наследования? Но как в таком случае быть, если потребуется изменить поведение программы из-за смены логики взаимодействия файлов с некоторыми группами владельцев?
Записан
nata267
Гость
« Ответ #6 : Июнь 07, 2012, 19:02 »

Оно конечно хорошо, но если речь о концепции, то лучше, наверное, пример взять поближе к простым смертным, на вроде меня. Обосновано ли использование медиатора в случае, если требуется взаимодействие, например, объектов файлов и объектов групп владельцев этих файлов между собой? Естественно, что один файл может быть доступен нескольким группам владельцев. Или достаточно наследования? Но как в таком случае быть, если потребуется изменить поведение программы из-за смены логики взаимодействия файлов с некоторыми группами владельцев?

Возможно и не обосновано, зависит от задачи. Приведите ваш пример. Просто я проектировала интерфейс графического редактора и у меня стояла такая задача. Я использовала singleton для предоставления глобальной точки доступа к компонентам. Вот не пойму какое решение лучше и в чем преимущества этих методов.
« Последнее редактирование: Июнь 07, 2012, 19:04 от nata267 » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Июнь 07, 2012, 19:05 »

Оно конечно хорошо, но если речь о концепции, то лучше, наверное, пример взять поближе к простым смертным, на вроде меня.
Именно так. Во-первых затруднительно вникнуть во все классы дизайнера. Лично я совсем не понял какова цель. Во-вторых, пример основывается на исходных классах с мощной ф-циональностью, в этом случае может проходить все что угодно - но это ни о чем не говорит. Более простой, житейский пример был бы более уместен
Записан
nata267
Гость
« Ответ #8 : Июнь 07, 2012, 19:15 »

Оно конечно хорошо, но если речь о концепции, то лучше, наверное, пример взять поближе к простым смертным, на вроде меня.
Именно так. Во-первых затруднительно вникнуть во все классы дизайнера. Лично я совсем не понял какова цель. Во-вторых, пример основывается на исходных классах с мощной ф-циональностью, в этом случае может проходить все что угодно - но это ни о чем не говорит. Более простой, житейский пример был бы более уместен

Да вроде бы простой пример, я же не приводила объявления классов и методов целиком, выделила только то что относится к данному вопросу, чтобы была понятна суть. Мне как раз таки и приходилось решать именно эту задачу. Думаю простые задачи, которые вы хотите чтобы я привела в пример, как раз и решаются простым наследованием. Паттерны нужны когда решаются более сложные задачи.
Записан
alexis031182
Гость
« Ответ #9 : Июнь 07, 2012, 19:25 »

Возможно и не обосновано, зависит от задачи. Приведите ваш пример.
Я пример задачи и привёл, просто образно, без кода. Мне лично самому проще так воспринимать. Спросил мнение тех, кто сильно в теме.

Просто я проектировала интерфейс графического редактора и у меня стояла такая задача. Я использовала singleton для предоставления глобальной точки доступа к компонентам. Вот не пойму какое решение лучше и в чем преимущества этих методов.
По моему мнению, медиатор в отличие от синглтона более специфичен. Он предназначен для работы с конкретными объектами. Если для целей, аналогичных Вашим, использовать синглтон, то тот довольно быстро превратится в указателе-помойку. Ну разве что тогда создавать кучу специфичных синглтонов, но это мне кажется тоже не выход. Вообще, чем меньше глобального доступа, тем лучше.

Медиатор локален, и весь код, относящийся к взаимодействию конкретных объектов описан только в нём. Это означает, что в случае, если потребуется изменить действия над некоторыми объектами из общего состава, то эти изменения можно будет внести непосредственно в сам Медиатор (допустим, через тоже наследование). Не потребуется вмешиваться в логику самих объектов, которых этот медиатор контролирует.
Записан
nata267
Гость
« Ответ #10 : Июнь 07, 2012, 19:26 »

Я вообще-то новичок в паттернах, хотелось бы их обсудить, так как при приеме на работу обычно требуют их знание и умение их применять. Вот хотелось бы вписываться в данный формат. Думаю опытные программисты здесь являются гуру паттернов. Лично меня при приеме на работу ими пытали неоднократно.
Записан
nata267
Гость
« Ответ #11 : Июнь 07, 2012, 19:33 »

Возможно и не обосновано, зависит от задачи. Приведите ваш пример.
Я пример задачи и привёл, просто образно, без кода. Мне лично самому проще так воспринимать. Спросил мнение тех, кто сильно в теме.

Просто я проектировала интерфейс графического редактора и у меня стояла такая задача. Я использовала singleton для предоставления глобальной точки доступа к компонентам. Вот не пойму какое решение лучше и в чем преимущества этих методов.
По моему мнению, медиатор в отличие от синглтона более специфичен. Он предназначен для работы с конкретными объектами. Если для целей, аналогичных Вашим, использовать синглтон, то тот довольно быстро превратится в указателе-помойку. Ну разве что тогда создавать кучу специфичных синглтонов, но это мне кажется тоже не выход. Вообще, чем меньше глобального доступа, тем лучше.

Медиатор локален, и весь код, относящийся к взаимодействию конкретных объектов описан только в нём. Это означает, что в случае, если потребуется изменить действия над некоторыми объектами из общего состава, то эти изменения можно будет внести непосредственно в сам Медиатор (допустим, через тоже наследование). Не потребуется вмешиваться в логику самих объектов, которых этот медиатор контролирует.

Да мне тоже понравилось решение. Но что код очень сложен для понимания - это минус. Классы разнесены по разным файлам. Пока соберешь картину целиком, голову сломаешь.
Записан
alexis031182
Гость
« Ответ #12 : Июнь 07, 2012, 19:40 »

Да мне тоже понравилось решение. Но что код очень сложен для понимания - это минус. Классы разнесены по разным файлам. Пока соберешь картину целиком, голову сломаешь.
А всё потому, что патерны в чистом виде наверное и не применяются. Обязательно хоть какая-то отсебятина будет. А без неё никак, поскольку непременно в каждом случае существует специфика задачи. Да даже просто нет стандарта в именовании классов. Я вот и имею представление о медиаторе, но Ваш код понять не сумел Улыбающийся
Записан
nata267
Гость
« Ответ #13 : Июнь 07, 2012, 19:45 »

Да мне тоже понравилось решение. Но что код очень сложен для понимания - это минус. Классы разнесены по разным файлам. Пока соберешь картину целиком, голову сломаешь.
А всё потому, что патерны в чистом виде наверное и не применяются. Обязательно хоть какая-то отсебятина будет. А без неё никак, поскольку непременно в каждом случае существует специфика задачи. Да даже просто нет стандарта в именовании классов. Я вот и имею представление о медиаторе, но Ваш код понять не сумел Улыбающийся

это не мой код, а тех кто писал дизайнер. наверно я не сумела донести идею(((
Записан
alexis031182
Гость
« Ответ #14 : Июнь 07, 2012, 19:50 »

это не мой код, а тех кто писал дизайнер. наверно я не сумела донести идею(((
Просто он порезан в листингах. Часть описания взаимодействия Вы привели словами, часть в коде. Да и много его, чтобы, извините, с кондачка въехать.
Записан
Страниц: [1] 2 3 ... 5   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.057 секунд. Запросов: 22.