WH>>> Ну давай объясни мне чем Model-View-Controller отличается от Carrier-Rider-Mapper? Т>> А что у них общего, кроме магического числа 3? WH> А в чем разница?
S>...они придумали "паттерн". Им было очень обидно, что паттерн MVC изобрели не они.
Не знаю как можно спутать паттерны Model-View-Controller и Carrier-Rider-Mapper.
Model-View-Controller
Сама модель о вьюхах ничего не знает. Сущность паттерна MVC заключена в существовании некой обобщённой транспортной шины передачи сообщений от моделей к вьюхам. Тот кто изменил модель отправляет по этой транспортной шине broadcast сообщение о том, что он изменил такую-то модель и тот кто заинтересован пусть примет меры. Транспортная шина (сеть) знает какие вьюхи с какими моделями связаны и передаёт это сообщение кому следует.
Спускаясь на уровень синтаксического мышления:
DEFINITION Models;
TYPE
Model = POINTER TO ABSTRACT RECORD ... END;
Message = ABSTRACT RECORD ... END;
UpdateMsg = EXTENSIBLE RECORD (Message) END;
PROCEDURE Broadcast (model: Model; VAR msg: Message);
END Models.
Изменил модель model — вызови процедуру Models.Broadcast(model, myMsg) и сообщение myMsg будет доставлено тем вьюхам, которые связаны с model.
Carrier-Rider-Mapper
Carrier — это носитель (любой) информации (например: File, Socket, Document, Form, ... Server), которая может предоставляться одновременно нескольким клиентам.
Rider(ы) — это Reader или Writer — объекты считывающие или записывающие информацию в носитель. Носитель информации предоставляет доступ к хранимой внутри себя информации только посредством Rider-ов и ни как иначе. Rider-ы — это интерфейсы доступа к информации.
Mapper(ы) — это Scanner или Formatter — обёртки над Reader или Writer соответственно. Они осуществляют преобразование форматов потоков информации в удобные для клиентов форматы.
Спускаясь на уровень синтаксического мышления:
TYPE
Reader = POINTER TO ABSTRACT RECORD ... END;
Writer = POINTER TO ABSTRACT RECORD ... END;
Carrier = POINTER TO ABSTRACT RECORD
...
(c: Carrier) NewReader (): Reader, NEW, ABSTRACT;
(c: Carrier) NewWriter (): Writer, NEW, ABSTRACT;
...
END;
P. S. Сколько раз подряд нужно рухнуть с дуба, чтобы эти паттерны перепутать?
Сергей Губанов wrote: > # *Model-View-Controller* > Сама модель о вьюхах ничего не знает. Сущность паттерна MVC заключена в > существовании некой обобщённой транспортной шины передачи сообщений от > моделей к вьюхам. Тот кто изменил модель отправляет по этой транспортной > шине broadcast сообщение о том, что он изменил такую-то модель и тот кто > заинтересован пусть примет меры. Транспортная шина (сеть) знает какие > вьюхи с какими моделями связаны и передаёт это сообщение кому следует.
Какая еще "шина"????
* Model: The domain-specific representation of the information on
which the application operates. The model is another name for the domain
layer. Domain logic adds meaning to raw data (e.g. calculating if today
is the user's birthday, or the totals, taxes and shipping charges for
shopping cart items).
* View: Renders the model into a form suitable for interaction,
typically a user interface element. MVC is often seen in web
applications, where the view is the HTML page and the code which gathers
dynamic data for the page.
* Controller: Responds to events, typically user actions, and
invokes changes on the model and perhaps the view.
* Many applications use a persistent storage mechanism (such as a
database) to store data. MVC does not specifically mention this data
access layer, because it is understood to be underneath or encapsulated
by the Model.
> Изменил модель model — вызови процедуру Models.Broadcast(model, myMsg) и > сообщение myMsg будет доставлено тем вьюхам, которые связаны с model.
Это детали конкретной реализации (покажите мне как это сделать, если
видом является HTML-страница у пользователя в браузере).
> Carrier — это носитель (любой) информации (например: File, Socket, > Document, Form, ... Server), которая может предоставляться одновременно > нескольким клиентам.
"Model: The domain-specific representation of the information on which
the application operates."
> Rider(ы) — это Reader или Writer — объекты считывающие или записывающие > информацию в носитель. Носитель информации предоставляет доступ к > хранимой внутри себя информации только посредством Rider-ов и ни как > иначе. Rider-ы — это интерфейсы доступа к информации.
"* Controller: Responds to events, typically user actions, and invokes
changes on the model and perhaps the view."
> Mapper(ы) — это Scanner или Formatter — обёртки над Reader или Writer > соответственно. Они осуществляют преобразование форматов потоков > информации в удобные для клиентов форматы.
"* View: Renders the model into a form suitable for interaction,
typically a user interface element."
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[2]: Model-View-Controller и Carrier-Rider-Mapper
Здравствуйте, Cyberax, Вы писали:
C> Это детали конкретной реализации
Естественно это были детали — я так и сказал: "Спускаясь на уровень синтаксического мышления".
>> Carrier C> Model
>> Rider C> Controller
>> Mapper C> View
То есть Вы тоже разницы между MVC и CRM не понимаете...
Re[3]: Model-View-Controller и Carrier-Rider-Mapper
Сергей Губанов wrote: >> > Carrier > C> Model >> > Rider > C> Controller >> > Mapper > C> View > То есть Вы тоже разницы между MVC и CRM не понимаете...
Определения model/carrier и mapper/view совпадают практически полностью.
вот захотелось тоже пофилософствовать...
вот мне интересно, не привнесло ли использование МВС в таком его виде к непомерному усложнению проекта?
универсально его нельзя применять, только одно решение — вью отделить от контроллера(бизнес логики) в другой проект, сделать полностью типизированный контроллер — набор классов со строго определенными методами, а на вью вызывать эти методы, потом обновлять то что надо. там где у модели есть несколько видов — предусмотреть модель событий, чтобы централизировано отображать изменения. Если же городить всю эту универсальность, то при выполнении комплексного изменения модели вью будет рефрешиться несколько раз.
Меня интересует, почему все так рьяно стремятся следовать этой универсальности, которая проявляет себя только на словах, но никак не в коде — усложняет его. Это фреймворк, а использование фреймворков — зло. Нужно использовать независимые компоненты, комбинируя их при помощи медиатора — завязывая их тонкой оберткой, устанавливая связи между ними.
Используя же фрвк — мы пытаемся запихнуть в него максимум фич, которые нам по идее когда-нить потребуются, а это зло:
1. никогда его не напишешь, тк будешь его всегда переписывать;
2. код, написанный под него кишит свитчами и операциями приведения типов (вспомните струтса);
3. придется городить кучу мелких классов (так же схема требует);
4. придется иметь дело с хмл — подключение к фрвк;
5. потеря контроля компиляции.
Нужно разрабатывать код исходя из потребностей, не решать проблемы универсально — на будущее. Если в системе есть ненужный код — выбросьте его, ибо лишняя сложность — лишние затраты — времени, денег, потом своего авторитета...
в этом есть смысл???
Re[3]: Model-View-Controller и Carrier-Rider-Mapper
Здравствуйте, Damat_AE, Вы писали:
D_A> вот мне интересно, не привнесло ли использование МВС в таком его виде к непомерному усложнению проекта?
Не привело. И не проекта, это фрэймворк BlackBox-а.
D_A> Если же городить всю эту универсальность, то при выполнении комплексного изменения модели вью будет рефрешиться несколько раз.
Не будет — кроме Broadcast есть и другие процедуры (обратите внимание на скрипты и модификации):
PROCEDURE Broadcast (model: Model; VAR msg: Message)
Передать msg для model. Перед передачей параметр model присваивается полю model сообщения.
Фактически передача происходит, только если model.domain # NIL.
Broadcast вызывается моделями всякий раз, когда им требуется передать информацию отображениям, в которых они показываются. В отличие от Domaincast, Broadcast посылает msg только отображениям, которые обладают model как своей собственной.
Обработчик сообщения модели не может рекурсивно посылать другое сообщение.
PROCEDURE Domaincast (d: Stores.Domain; VAR msg: Message)
Эта процедура посылает сообщение конкретному домену, или не делает ничего, если домен равен NIL. Каждое отображение в домене получит сообщение. Обычно вы будете использовать Broadcast для уведомления отображений только конкретной модели. Domaincast необходим только, если содержимое некоторого отображения (например, текстовой линейки) влияет на что-либо вне самого отображения (например, форматирует текст после линейки). Domaincast фактически выполняется, только если d # NIL.
Domaincast может не выполниться, если другая передача происходит в данных момент для этого домена (не должно быть рекурсии).
PROCEDURE BeginModification (type: INTEGER; m: Model)
Если модель m изменяется таким образом, что это не может быть отменено, изменения должны быть "взяты в скобки" вызовами BeginModification и EndModification с параметров type, установленным в notUndoable.
PROCEDURE EndModification (type: INTEGER; m: Model)
Если модель m изменяется таким образом, что это не может быть отменено, изменения должны быть "взяты в скобки" вызовами BeginModification и EndModification с параметров type, установленным в notUndoable.
PROCEDURE BeginScript (m: Model; name: Stores.OpName; OUT script: Stores.Operation)
Чтобы сделать последовательность отменяемых операций отменяемыми как единое целое, эту последовательность следует "взять в скобки" BeginScript и EndScript.
PROCEDURE EndScript (m: Model; script: Stores.Operation)
Чтобы сделать последовательность отменяемых операций отменяемыми как единое целое, эту последовательность следует "взять в скобки" BeginScript и EndScript. В EndScript должен быть передан тот же script, который был возвращен BeginScript.
PROCEDURE Do (m: Model; name: Stores.OpName; op: Stores.Operation)
Эта процедура вызывается для выполнения операции на модели. Вызывается процедура Do операции, и операция записывается для последующей отмены.
PROCEDURE LastOp (m: Model): Stores.Operation
Эта процедура возвращает самую последнюю операцию, выполненную на данной модели. Это может использоваться для принятия решения о том, когда следует связать несколько успешных операций в одну единственную атомарную операцию, например, если в текст вводится символ, он может быть связан с предыдущим введенным символом; так что отмена будет применена сразу ко всему введенному тексту, а не к каждому символу отдельно.
PROCEDURE Bunch (m: Model)
Уведомляет модель, что другое действие было связано с самой последней выполненной операцией. После того, как будет установлено, что новая операция может быть слита с самой последней операцией (для теста используется LastOp), предыдущая операция может быть изменена (например, к ее строке добавлен символ, который был введен), и это изменение делается известным среде через вызов Bunch.
D_A> Меня интересует, почему все так рьяно стремятся следовать этой универсальности, которая проявляет себя только на словах, но никак не в коде — усложняет его. Это фреймворк, а использование фреймворков — зло.
Моё мнение противоположное.
Re[3]: Model-View-Controller и Carrier-Rider-Mapper
а не проще реализовать только то, что нужно?, полностью типизированные методы, просто отделение гуи от бизнес логики.
проект будет проще, его проще отлаживать, тестировать и поддерживать.
то, что Вы написали — просто кишит операциями приведения типов — признак плохого дизайна. Тянуть универсальность(наследоваться от базовых модели, там еще контроллера) только ради того, чтобы оповещать — не выход, потому что наследование нужно использовать осторожно — в шарпе нет множественного, а вдруг реально понадобится по смыслу пронаследоваться.
код подвержен ошибкам типа — передал модель одной подсистемы в контроллер другой (извините за терминологию, может там не передал, но все же смысл есть) — все ведь в хмл конфигурится. как выход — можна использовать абстрактную фабрику — даже тогда тоже самое.
попыток написать фрвк было не мало, особенно начиная изучать шарп, они все были реализованы, один — на джаве (секьюрити, вложенность функциональности с откатами — как в моб телефоне, еррор хэндлинг, параллельность тасков), но писать под такие фрвк — потеря гибкости,
вот так
Re[4]: Model-View-Controller и Carrier-Rider-Mapper
Здравствуйте, Damat_AE, Вы писали:
D_A> полностью типизированные методы
Вы хотите спросить почему используется обобщённый механизм посылки сообщений вместо механизма вызова соответствующих методов?
Ответ простой: добавить новый метод в уже опубликованный интерфейс нельзя, а добавить новый тип сообщения — запросто.
TYPE MyMessage = RECORD (Message) ... END;
VAR myMsg: MyMessage;
...
obj.Handle(myMsg);
Все старые модули при этом перекомпилировать не надо.
Построение систем на основе обобщённого механизма транспорта сообщений — самый простой способ построения расширяемых систем.
D_A> кишит операциями приведения типов — признак плохого дизайна.
Это Вы о чём?
D_A> потому что наследование нужно использовать осторожно — в шарпе нет множественного, а вдруг реально понадобится по смыслу пронаследоваться.
А при чём тут шарп и множественное наследование?
Re[5]: Model-View-Controller и Carrier-Rider-Mapper
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Здравствуйте, Damat_AE, Вы писали:
D_A>> полностью типизированные методы
СГ>Вы хотите спросить почему используется обобщённый механизм посылки сообщений вместо механизма вызова соответствующих методов?
СГ>Ответ простой: добавить новый метод в уже опубликованный интерфейс нельзя, а добавить новый тип сообщения — запросто.
СГ>TYPE MyMessage = RECORD (Message) ... END;
СГ>VAR myMsg: MyMessage; СГ>... СГ>obj.Handle(myMsg);
СГ>Все старые модули при этом перекомпилировать не надо.
думаю в системе не должно быть меньше модулей чем 3 и не больше чем мало
все это хорошо в приложении с плагин архитектурой, там только так, но длч обычного рода приложений — это отягощение.
возможно мы говорим о разных масштабах приложений? наверное, если оно огромное и содержит множество подсистем — имеет смысл,
но опять же, ядро системы должно предоставлять богатый интерфейс — контексты, а клиент просто с ними работает.
ну например, главное окно приложения — контекст, в котором крутятся плагины. Есть объекты в контексте для встраивания в меню,
работа со статус баром, доступ к документу.
как по мне, логика, обрабатывающая сообщения и их перенаправляющая — непомерно мала, чтобы ее реализовывать в качестве базовой.
я видел в интерфейсе класс Модель — походу от нее надо бы пронаследоваться походу, или контроллер наследуетс, или вью, или все
сразу. Это и есть ответ на то, что метод обработки сообщений на контроллере должен привести модель к конкретному типу — а он может
не совпасть.
расскажите, что это за система, тогда будет яснее
Re[6]: Model-View-Controller и Carrier-Rider-Mapper