Здравствуйте. Хочу разобраться с архитектурными паттернами MVC, MVP, и понять с какой архитектурой я имею дело, если точнее — понять какую именно архитектуру я создаю. Сразу оговорюсь создается desktop приложение.
Про MVC.
Поверхностно с MVC знаком довольно давно. Сейчас стал разбираться и понял, что один момент в архитектуре паттерна меня категорически не устраивает: Представление имеет ссылку на Модель. Моя задача изначально поставлена так, что на модель придется 2 и более представления.
1) Получается, что Представления потянут всю или почти всю иерархию модели. Модель, нужно сказать, спроектирована в лучших традициях ООП. Т.е. когда я буду иметь модель (одну или более) и 6 представлений, то из-за такой простой операции как переименование класса в модели, мне придется вносить изменения, перекомпилировать представления?
2) Представим что, Представление, форма напичканная элементами управления, или ее полностью заменяемый, более наглядный, аналог – рисуемые на холсте диаграммы, настолько удачно подобранны и настолько хорошо спроектированы, что могут использоваться как кнопка. Могут подходить к разным моделям ситуациям и т.д. Паттерн фактически обязывает привязать эту «кнопку» к конкретной модели. Возникает вопрос – кому нужна такая «кнопка»?
Про MVP.
С описанной выше точки зрения на эти паттерны, я быстро понял – то, что я создаю не MVC. У меня был интерфейс представления, с неким простым набором операций, отвязанный от какой-либо модели. Так же у Представления есть интерфейс контроллера (презентер), необходимый представлению для работы. Таким образом, контроллер не зависит от конкретного представления, представление не зависит от конкретного контроллера. Связность минимальна. Контроллер (Презентер), знает об интерфейсе Представления и знает о модели. Модель не знает вообще ничего.
Что я имею. Я имею три почти несвязных компоненты: Модель, Презентер, Представление. Связанность тут: конкретный презентер зависит от модели. Все взаимодействие Модель – Представление происходит через Презентер. Является ли то, что я построил MVP?
Здравствуйте, idxDmitry, Вы писали:
D>Здравствуйте. Хочу разобраться с архитектурными паттернами MVC, MVP, и понять с какой архитектурой я имею дело, если точнее — понять какую именно архитектуру я создаю. Сразу оговорюсь создается desktop приложение. D>Про MVC. D>Поверхностно с MVC знаком довольно давно. Сейчас стал разбираться и понял, что один момент в архитектуре паттерна меня категорически не устраивает: Представление имеет ссылку на Модель. Моя задача изначально поставлена так, что на модель придется 2 и более представления.
Это классические отношение один ко многим и никакого противоречия тут нет. Вот если б у вас модель имела ссылку на представление, тогда да, сложно будет делать несколько представлений.
Вообще, патерны патернами, а работу надо сдавать. То, что вы делаете должно быть читаемо (в первую очередь) и расширябельно. Под какой патерн оно при этом подходит — какая разница?
Здравствуйте, idxDmitry, Вы писали:
D>Здравствуйте. Хочу разобраться с архитектурными паттернами MVC, MVP, и понять с какой архитектурой я имею дело, если точнее — понять какую именно архитектуру я создаю. Сразу оговорюсь создается desktop приложение. D>Про MVC. D>Поверхностно с MVC знаком довольно давно. Сейчас стал разбираться и понял, что один момент в архитектуре паттерна меня категорически не устраивает: Представление имеет ссылку на Модель. Моя задача изначально поставлена так, что на модель придется 2 и более представления. D>1) Получается, что Представления потянут всю или почти всю иерархию модели. Модель, нужно сказать, спроектирована в лучших традициях ООП. Т.е. когда я буду иметь модель (одну или более) и 6 представлений, то из-за такой простой операции как переименование класса в модели, мне придется вносить изменения, перекомпилировать представления?
Из-за такой простой операции вам придётся сделать другую простую операцию — называется поиск с заменой. В современных IDE в меню с громким названием Рефакторинг это автоматизировано. Да, придётся перекомпилировать. (это нормально и не страшно)
А если что-то меняется без перекомпиляции, то это уже система динамически подгружаемых плагинов и к патернам она перпендикулярна. То есть вы можете иметь плагины без MVC, можете наоборот, можете вместе, это неважно.
Кстати, в лучших традициях ООП рекомендуют создавать интерфейсы, чтобы простая операция переименования класса была прозрачной для других частей кода. С другой стороны, вы ведь и название интерфейса можете захотеть поменять. Что ещё раз подчёркивает — не надо бояться переименований, не надо искать патернов, которые позволяют избежать перекомпиляции.
Здравствуйте, idxDmitry, Вы писали:
D>Здравствуйте. Хочу разобраться с архитектурными паттернами MVC, MVP, и понять с какой архитектурой я имею дело, если точнее — понять какую именно архитектуру я создаю. Сразу оговорюсь создается desktop приложение. D>Про MVC.
[...] D>2) Представим что, Представление, форма напичканная элементами управления, или ее полностью заменяемый, более наглядный, аналог – рисуемые на холсте диаграммы, настолько удачно подобранны и настолько хорошо спроектированы, что могут использоваться как кнопка. Могут подходить к разным моделям ситуациям и т.д. Паттерн фактически обязывает привязать эту «кнопку» к конкретной модели. Возникает вопрос – кому нужна такая «кнопка»?
Это прекрасный вопрос.
Никому она не нужна. Вот если б вы разрабатывали оконную систему или движок хранения данных, типа Berkley DB, то да, там component reuse во весь рост. А тут не будет повторного использования. Вы делаете конкретное приложение, пользователя интересует готовый продукт.
С другой стороны, можно понять MVC иначе. Патерн обязывает придумать некоторый интерфейс для модели, представления; так что в будущем будет относительно несложно заменить один из компонентов. Это не значит, что всё должно работать просто заменой дллки (это плагины), но если рассматривать модель, представление, все части как чёрные ящики, к которым у вас нет доступа пока вы работаете над другим ящиком, то в будущем замена будет проще.
Temoto уже все рассказал. Я только чуть-чуть добавлю.
Можно опираться на шаблон Layers чтобы понимать какие изменения повлекут
за собой другие изменения. Вот простенькая диаграмма одной из вариаций
шаблона layers: http://www.soldatenko.ru/userfiles/a0a0a/craig%20larmar%20layers.jpg
Поскольку модель из MVC это скорее "Уровень объектов предметной
области", или, максимум "Уровень приложения", а View — это безусловно
"уровень представления", то естественно, что изменение в модели повчечет
изменение в представлении.
Другое дело, что вас никто не заставляет связывать View с вашей
конкретной моделью. Связывайте со специально определенными интерфейсами,
и обслуживайте классы которые опираясь на модель будут поддерживать
интерфейсы для View. Но тогда, при изменении моделии придется
переделывать классы-посредники.
По части того, является ли ваше решение MVC — можно легко проверить.
— Есть ли ссылки в модели на View (кроме ссылок на EventListeners)?
— Да — НЕ MVC, Нет — см. ниже.
— Прилетает ли событие из модели, при каждом изменении каких либо данных
в модели (данных доступных извне)?
— Нет — НЕ MVC. Да — См. ниже.
— Отслеживает ли View события из модели и обновляет отображаемые данные
от Event-ов?
— Нет — НЕ MVC, Да — см. ниже
— Использует ли View какой-нибудь интерфейс для передачи сообщений
(вызова методов) в модель? Это может быть даже EventListener по которому
события передаются из View в Model. Или в этом качестве может
использоваться сама модель (со всеми методами и свойствами!).
— Да — MVC. нет — НЕ MVC.
Большое спасибо Temoto и Other Sam. Всегда приятно получить содержательный ответ.
Стала понятней ситуация с MVC. Пожалуй, вы правы, и мои опасения по поводу связи представления и модели преувеличины. Ясно, что моя модель не является MVC и пока я решил не переходить к этой модели, потому что часть кода уже написана в другой архитектуре. На мой взгляд (возможно я ошибаюсь) в архитектуре более эффективной — все же представление пока отвязано от модели. Я вижу этот подход более подходящим еще по той причине, что отражение модели на представление тоже несет в себе полезный общий код, вынесение которого делает представления более легкими. Хотя, обеспечение меньшей связности требует больше времени. Вот собственно, проблемы обеспечения подобного уровня связности меня и побудили задать вопрос.
Для меня остается открытым является ли моя архитектура MVP или какой-то другой. Почему для меня это важно? Потому что я не знаю как правильно обеспечивать связь между представлением и моделью при таком уровне связности. Если говорить конкретнее: я не знаю как правильно по моей модели заполнять представление, поддерживать его в актуальном состоянии, а также изменять модель по представлению при этом оставляя их несвязными. Я посмотрел на MVP, там связности представления и модели нет, а следовательно это как-то реализовано.
Сейчас это сделано так. Контроллер (презентер) передает представлению примитивные данные — строки, числа, и т.п. необходимые для того чтобы заполнять, деревья, списки и прочие элементы, а вместе с ними передает ссылки на реальные объекты модели, ссылки не конкретных типов, а указателей (или супертипов). Затем по этим ссылкам контроллер догадывается с каким объектом нужно проделать ту или иную операцию.
Пока писал, подумал, что, похоже, не имеет значения знает представление о модели или нет — проблема связи модели с GUI, от этого, видимо, не зависит..
Короче говоря, очень хотелось бы узнать, какую же все-таки архитектуру я построил, и самое главное — как это сделать правильно. Как правильно обеспечить связь представления и модели на таком уровне связности?
Здравствуйте, idxDmitry, Вы писали:
D>Про MVP. D>С описанной выше точки зрения на эти паттерны, я быстро понял – то, что я создаю не MVC. У меня был интерфейс представления, с неким простым набором операций, отвязанный от какой-либо модели. Так же у Представления есть интерфейс контроллера (презентер), необходимый представлению для работы.
зачем представлению знать интерфейс контроллера?
у меня например, представление через фабрику инстанцирует контроллер, а дальше уже контроллер обращается к представлению через интерфейс.
// псевдокод во view
IPresenter presenter= PresenterFactory.CreatePresenter(this, /* при необходимости action type */);
presenter.Execute();
D> Таким образом, контроллер не зависит от конкретного представления, представление не зависит от конкретного контроллера. Связность минимальна. Контроллер (Презентер), знает об интерфейсе Представления и знает о модели. Модель не знает вообще ничего. D>Что я имею. Я имею три почти несвязных компоненты: Модель, Презентер, Представление. Связанность тут: конкретный презентер зависит от модели. Все взаимодействие Модель – Представление происходит через Презентер. Является ли то, что я построил MVP?
очень похоже на MVP, я тебе действительно так важно как это называется?
Тут вон споры идут, считать ли transaction script анемиком или нет, у тебя из той же серии?
ИМНО если дизайн приложения легко поддерживаем и расширяем, то какая разница как он называется?
... << RSDN@Home 1.2.0 alpha 4 rev. 1270>>
Re[2]: MVC, MVP и прочие
От:
Аноним
Дата:
11.01.10 15:41
Оценка:
Здравствуйте, cadet354, Вы писали:
C>зачем представлению знать интерфейс контроллера?
Ну я написал не совсем верно. Конкретное представление знает лишь об интерфейсе той части контроллера, которая ей необходима. Этот интерфейс описан в модуле формы. А Презентер его реализует. Аналогом могут являться события Представления, но на солидное Представление этих событий набирается столько, что проще объединить их в интерфейс.
Re[3]: MVC, MVP и прочие
От:
Аноним
Дата:
11.01.10 15:49
Оценка:
Здравствуйте, Semper Fidelis, Вы писали:
SF>Посмотрите вот эту статью GUI Architectures. В ней описаны различные разновидности MVC/MVP паттернов.
Мне показалось что под "моделью" вы понимаете реализацию прикладной логики и данные. Но в MVC "моделью" называют достаточно тонкий интерфейс предоставляющий наружу четко оговоренные данные.
Например модель "таблица" может предоставлять класс с несколькими методами получения содержимого таблицы. И реализаций таких моделей может быть масса в одной программе.