MVC (Модель, Представление, Контроллер) - это шаблон для организации кода в приложении для улучшения удобства сопровождения.
Представьте себе фотографа с его камерой в студии. Клиент просит его сфотографировать коробку.
Не-MVC архитектуры, как правило, тесно связаны друг с другом. Если бы коробка, контроллер и камера были одним и тем же объектом, то нам пришлось бы разбирать и затем заново собирать и коробку, и камеру каждый раз, когда мы хотели получить новый вид. Кроме того, фотографировать - это все равно, что делать селфи, а это не всегда легко.
бваха написал:
Автор ссылается на mvctree.py в wxPython как пример дизайна MVC. Однако я все еще слишком зелен, поэтому нахожу этот конкретный пример слишком сложным и не понимаю разделения, которое рекомендует автор.
MVC это все о разделении интересов.
Модель отвечает за управление данными программы (как частными, так и клиентскими данными). View / Controller отвечает за обеспечение внешнего мира средствами взаимодействия с данными клиента программы.
Модель предоставляет внутренний интерфейс (API), позволяющий взаимодействовать с ней другим частям программы. View / Controller предоставляет внешний интерфейс (GUI / CLI / веб-форма / высокоуровневый IPC / и т. Д.), Который позволяет всем программам взаимодействовать с ним.
Модель отвечает за поддержание целостности данных программы, потому что, если она будет повреждена, игра для всех закончена. View / Controller отвечает за поддержание целостности пользовательского интерфейса, следя за тем, чтобы все текстовые представления отображали актуальные значения, отключая пункты меню, которые не относятся к текущему фокусу, и т. Д.
Модель не содержит кода вида / контроллера; нет классов графического интерфейса, нет кода для размещения диалоговых окон или получения пользовательского ввода. Вид / Контроллер не содержит кода модели; нет кода для проверки URL-адресов или выполнения запросов SQL, а также нет исходного состояния: любые данные, хранящиеся в виджетах, предназначены только для отображения и являются просто отражением истинных данных, хранящихся в модели.
Итак, вот проверка истинного дизайна MVC: программа должна быть полностью функциональной, даже если к ней не подключен View / Controller. ОК, у внешнего мира будут проблемы с взаимодействием с ним в этой форме, но, пока кто-то знает соответствующие заклинания Model API, программа будет хранить и манипулировать данными как обычно.
Почему это возможно? Ответ прост: все благодаря слабой связи между слоями Model и View / Controller. Тем не менее, это не полная история. Что ключ ко всему шаблону MVC является направлением , в котором те соединения идут: ВСЕ инструкции поток из Вида / контроллера к модели. Модель НИКОГДА не говорит View / Controller, что делать.
Почему? Потому что в MVC, хотя View / Controller разрешено немного знать о Модели (в частности, API Модели), но Model не разрешается вообще ничего знать о View / Controller.
Почему? Потому что MVC - это создание четкого разделения интересов.
Почему? Чтобы помочь предотвратить сложность программы, выходящую из-под контроля и скрывающую вас, разработчика, под ней. Чем больше программа, тем больше число компонентов в этой программе. И чем больше связей существует между этими компонентами, тем сложнее разработчикам поддерживать / расширять / заменять отдельные компоненты или даже просто следить за работой всей системы. Задайте себе вопрос: при взгляде на диаграмму структуры программы, вы бы предпочли увидеть дерево или кошачью колыбель? Шаблон MVC позволяет избежать последнего путем запрета круговых соединений: B может подключаться к A, но A не может подключаться к B. В этом случае A - это модель, а B - представление / контроллер.
Кстати, если вы сообразительны, вы заметите проблему с только что описанным «односторонним» ограничением: как Модель может информировать View / Controller об изменениях в пользовательских данных Модели, когда Модель даже не имеет права знаете, что View / Controller, не говоря уже о том, чтобы отправлять на него сообщения? Но не волнуйтесь: есть решение для этого, и оно довольно опрятное, даже если на первый взгляд оно кажется довольно окольным. Мы вернемся к этому через минуту.
Таким образом, в практическом плане объект View / Controller может через API модели: 1. сказать модели делать что-либо (выполнить команды) и 2. сказать модели дать ей вещи (вернуть данные). Слой View / Controller
передает инструкции на слой Model и извлекает информацию из слоя Model.
И вот где ваш первый пример MyCoolListControl идет не так, потому что API для этого класса требует , чтобы информация толкнул
в нее, так что вы вернулись к тому , двухстороннюю связь между слоями, нарушение правил MVC и демпинг вас обратно в архитектура кошачьей колыбели, которую вы [предположительно] пытались избежать в первую очередь.
Вместо этого класс MyCoolListControl должен идти с потоком, извлекая необходимые данные из слоя ниже, когда это необходимо. В случае виджета списка это обычно означает запрос количества значений, а затем запрос каждого из этих элементов по очереди, потому что это самый простой и самый простой способ сделать это и, следовательно, свести к минимуму связь. И если виджет хочет, скажем, представить эти значения пользователю в хорошем алфавитном порядке, то это его перогатив; и его ответственность, конечно.
Теперь, последняя загадка, как я уже упоминал ранее: как вы синхронизируете отображение интерфейса пользователя с состоянием модели в системе на основе MVC?
Вот проблема: многие объекты View имеют состояние, например, флажок может быть отмечен или не отмечен, текстовое поле может содержать некоторый редактируемый текст. Однако MVC требует, чтобы все пользовательские данные были сохранены на уровне модели, поэтому любые данные, хранящиеся в других слоях для целей отображения (состояние флажка, текущий текст текстового поля), должны, следовательно, быть вспомогательной копией этих первичных данных модели. Но если состояние модели изменится, копия этого состояния в представлении больше не будет точной и нуждается в обновлении.
Но как? Шаблон MVC не позволяет модели помещать свежую копию этой информации в слой просмотра. Черт возьми, он даже не позволяет модели отправлять View сообщение о том, что его состояние изменилось.
Ну, почти. Хорошо, слою модели не разрешено напрямую общаться с другими уровнями, поскольку для этого потребуется, чтобы он что-то знал об этих слоях, а правила MVC препятствуют этому. Тем не менее, если дерево падает в лесу и его никто не слышит, издается ли оно?
Ответ, вы видите, состоит в том, чтобы настроить систему уведомлений, предоставляя слою Model место, где он может никому не сообщать, в частности, что он только что сделал что-то интересное. Затем другие слои могут публиковать слушателей с помощью этой системы уведомлений для прослушивания тех объявлений, которые им действительно интересны. Слой модели не должен ничего знать о том, кто слушает (или даже если кто-то вообще слушает!); он просто публикует объявление, а затем забывает об этом. И если кто-то услышит это объявление и захочет что-то сделать потом - например, запросить у модели какие-то новые данные, чтобы она могла обновить свой экранный дисплей - тогда замечательно. Модель просто перечисляет, какие уведомления она отправляет как часть своего определения API; и то, что кто-то еще делает с этим знанием, зависит от них.
MVC сохранился, и все счастливы. Ваша прикладная среда вполне может обеспечить встроенную систему уведомлений, или вы можете написать свою собственную, если нет (см. «Шаблон наблюдателя»).
...
Во всяком случае, надеюсь, что это помогает. Как только вы поймете мотивы, стоящие за MVC, причины, по которым все делается так, как они есть, начинают иметь смысл, даже когда - на первый взгляд - они кажутся более сложными, чем необходимо.
Ура,
имеет