Название: Разделяю один объект на два. Как правильно сделать их взаимодействие? Отправлено: xintrea от Ноябрь 06, 2015, 20:11 Дошли у меня руки поковыряться с застаревшим кодом. Надо его потихоньку приводить в более удобоваримое состояние. Проект - это простой WYSIWING редактор, используемый в составе программы MyTetra.
Основной файл - editor.cpp (класс Editor). https://github.com/xintrea/mytetra_dev/tree/editorModification/src/libraries/wyedit Сий редактор был сделан на скорую руку на основе стандартного примера из Qt. И все объекты кнопок управления ранее находились прямо в классе Editor. Сейчас я выделяю из класса Editor класс панели с кнопками, называемый EditorToolBar. И вот вопрос. После выделения кнопок в отдельный класс, внутри этого нового класса нужны обращения к вышестоящему виджету (т. е. к классу Editor) для следующих действий: 1. Получение конфига редактора (от нескольких переменных конфига зависит расположение кнопок и прочих элементов управления, размещенных на EditorToolBar) 2. Текущий режим отображения редактора (от режима зависит видимость и действия кнопок и прочих элементов EditorToolBar) 3. Enum допустимых режимов редактора (чтобы было с чем сравнивать при действиях в пункте 2) Я бы мог обращаться к родительскому виджету для получения всех этих данных. Но я недавно прочитал статью Чистая архитектура (http://habrahabr.ru/post/269589/) и там написано, что обращения к вышестоящим по иерархии объектам должны быть совершенно исключены. А я не могу придумать, как же мне не обращаться к parent-виджету для получения нужных мне данных. Как поступить в случае, когда есть главный объект редактора, и второстепенный объект тулбара? Как сделать такой тулбар, чтобы он не требовал данных от редактора? Да и нужно ли такой делать? Название: Re: Разделяю один объект на два. Как правильно сделать их взаимодействие? Отправлено: Old от Ноябрь 06, 2015, 20:23 1. Получение конфига редактора (от нескольких переменных конфига зависит расположение кнопок и прочих элементов управления, размещенных на EditorToolBar) Эти конфиги можно передать тулбару при конструировании, но лучше что-бы редактор сам его настраивал вызывая его методы.2. Текущий режим отображения редактора (от режима зависит видимость и действия кнопок и прочих элементов EditorToolBar) Сделайте слот у тулбара, например, setMode, и свяжите его с сигналом редактора, который испускается при смене режима.3. Enum допустимых режимов редактора (чтобы было с чем сравнивать при действиях в пункте 2) Тулбару должно быть все равно, какой режим ему устанавливают, это забота родительского редактора.Название: Re: Разделяю один объект на два. Как правильно сделать их взаимодействие? Отправлено: Racheengel от Ноябрь 07, 2015, 01:08 По моему, почти классический mvc. Editor это модель и вью в одном целом, тулбар это контроллер. Тулбар должен обсервировать модель данных редактора и в соответствии с ней менять себя (включать и выключать кнопки и т.д.). Когда юзером нажата какая либо кнопка тулбара, должен вызываться соответствущий метод редактора. Он в свою очередь поменяет модель данных, что отразится на тулбаре.
Название: Re: Разделяю один объект на два. Как правильно сделать их взаимодействие? Отправлено: Igors от Ноябрь 07, 2015, 13:36 Напрашивается "интерфейс", т.е. методы нужные тулбару выделяются в отдельный класс, и указатель на него дается тулбару. Сам класс включается в Editor наследованием или агрегированием. Можно "замылить" это слот/сигналами, но суть от этого не изменится.
Порадовали статейкой :) Цитировать 1. Независимость от фреймворка. Архитектура не зависит от существования какой-либо библиотеки. Это позволяет использовать фреймворк в качестве инструмента, вместо того, чтобы втискивать свою систему в рамки его ограничений. Хммм... а что же будет если вот "отнимут" Qt? (или дуст и др) Останется ли "хоть что-нибудь"? :)Название: Re: Разделяю один объект на два. Как правильно сделать их взаимодействие? Отправлено: Racheengel от Ноябрь 07, 2015, 14:16 Как то так,да. Едитор ведь и без тулбара существовать может, а тулбар без едитора смысла не имеет. Пусть тулбар сам и цепляется к модели редактора.
Название: Re: Разделяю один объект на два. Как правильно сделать их взаимодействие? Отправлено: ssoft от Ноябрь 09, 2015, 08:17 EditorToolBar - это панель с кнопками и ничего более.
Для наличия вышеперечисленной функциональности необходима дополнительная внешняя сущность(ти), которая управляет состояниями EditorToolBar. Каким образом предполагалось обращение EditorToolBar к вышестоящему виджету для изменения его состояния, по таймеру? Иначе это всегда внешнее воздействие на EditorToolBar - через метод update, сигнал слот. Управляющей сущностью может быть сам Editior в случае, если очень лень писать, но по-хорошему это должен быть отдельный тип. При проектировании архитектуры всегда необходимо руководствоваться необходимостью дальнейшего сопровождения - в том числе легкого изменения поведения программы (например, настройки передаются по сети или добавились новые режимы работы) и возможности повторного использования ее компонентов без необходимости их модификации. Название: Re: Разделяю один объект на два. Как правильно сделать их взаимодействие? Отправлено: Racheengel от Ноябрь 09, 2015, 19:57 Для наличия вышеперечисленной функциональности необходима дополнительная внешняя сущность(ти), которая управляет состояниями EditorToolBar. Состояние EditorToolBar зависит от модели редактируемого докуметна. Это может быть позиция курсора, текущее выделение и т.д. Поскольку интерфейс данной модели, как правило, экспортируется редактором с помощью сигналов и слотов, то EditorToolBar здесь выступает в роли контроллера, присоединенного к этим сигналам и слотов. Он реагирует на сигналы изменения модели и имплементирует обратную связь посредством соединения своих сигналов и слотов редактора. Зачем тут еще одна сущность? Название: Re: Разделяю один объект на два. Как правильно сделать их взаимодействие? Отправлено: ssoft от Ноябрь 10, 2015, 09:29 Чаще всего так и делают (я не исключение), если не хотят заморачиваться - весь функционал реализуют в EditorToolBar, назначая ему кроме других ролей и роль контроллера. Помещают туда и загрузку из конфига, и реакцию на мышь, и др.
Количество кода EditorToolBar разрастается, повторное использование затрудняется. По хорошему, если рассмотреть EditorToolBar, как автономный объект, который может просто переключаться в разные состояния, тем более что они перечислены в enum, то вызвать метод (слот) изменения состояния у EditorToolBar должен внешний(е) объект(ы), например, EditorToolBarConfig - загрузчик состояния из конфига, EditorToolBarMousePosition - изменяет состояние EditorToolBar по мышиным событиям, EditorToolBarDocumentModel - изменяет состояние EditorToolBar в зависимости от модели документа и т.п. Название: Re: Разделяю один объект на два. Как правильно сделать их взаимодействие? Отправлено: Racheengel от Ноябрь 10, 2015, 11:56 весь функционал реализуют в EditorToolBar, назначая ему кроме других ролей и роль контроллера. Помещают туда и загрузку из конфига, и реакцию на мышь, и др. Тулбар загружает данные из конфига - это, конечно, высокое мастерство индокодерства :) Но обычно быдлокодеры не так делают, они все в редахтор лепят, и тулбары, и загрузку, и все остальное :) Но вещи типа EditorToolBarConfig и EditorToolBarMousePosition тоже не должны ничего знать о тулбаре. Загрузка из конфига изменяет модель данных редактора. Тулбар же по сути туп - он вообще может рассматриваться как некий набор экшенов. А вот экшены уже должны быть связаны с редактором. Т.е. тулбар не должен обладать знаниями о том, КТО модифицирует модель. Ему только надо знать, ЧТО было модифицировано. Этим сильно упрощается архитектура. |