MVC vs API. Ваше мнение.
Вложений: 2
Всем мир.
В приложении есть набор модулей/плагинов/виджетов. Необходимо реализовать взаимодействие между ними. Давайте с вами разберём два основных подхода клиентского программирования: Первый вариант для многих знаком и привычен. Суть его в том, что каждый модуль имеет внешнее API, посредством которого можно управлять им (модулем) из стороннего модуля. Схематично это выглядит примерно так: http://javascript.ru/forum/attachmen...1&d=1279616659 Обращение одного модуля к другому указано стрелками между ними. Так же может быть (может и не быть) контроллер этих плагинов со своим API. Контроллер может иметь функционал добавления/удаления модулей, получение API определённого модуля, если ссылка была потеряна и так далее. Что я думаю о таком варианте: + API позволяет напрямую изменять другие модули. На первый взгляд все логично и удобно. - Модули зависят друг от друга. Логика обращений из одного модуля к другому зашита внутри кода первого и наоборот. При смене API одного, менять нужно все, которые его (API) используют. - Изменение ответов сервера влечет изменение клиентской части. - Не соответствует архитектуре MVC. Если один модуль отвечает за бизнес логику и в нем происходят какие-либо изменения, их должен отобразить другой модуль. В этом случае граница между ними становится размытой. Такой подход я наблюдаю повсюду. Всеми любимый jQuery тому пример. Второй вариант использует событийную архитектуру. Суть его в том, что каждый модуль реагирует на определённые события, присылаемые контроллером, которые в свою очередь генерирует источник события. Схематично это выглядит так: http://javascript.ru/forum/attachmen...1&d=1279618583 Источник события может быть данными, а может быть и самим модулем. Чтобы это работало, при инициализации каждый модуль регистрируется контроллером и передаёт ему список событий, на которые он может реагировать. Таким образом, любой источник события может повлечь за собой изменение сразу нескольких модулей, о которых он совершенно ничего не знает, поэтому ни от кого не зависит. Что я думаю о таком варианте: При таком подходе все минусы первого варианта становятся плюсами и наоборот. Для меня выбор очевиден, но хотел бы спросить вас: в каком варианте вам было бы удобнее поддерживать/развивать чужое приложение? К примеру, если вы работаете в команде, какой подход бы вы выбрали? Или может у кого есть другие варианты? Спасибо. |
B~Vladi,
Мне кажется это зависит от поставленной задачи и в каком виде это будет применяться. Я бы выбирал так: Если нужно более безопасное приложение то 2, а если более гибкое то 1. |
Цитата:
Цитата:
|
Цитата:
Цитата:
$('input[name=data].active:checked') подразумевает, что приложение должно знать какие данные ему нужны, какое представление они сейчас имеют и какое логическое состояние оно должно иметь. Любой плагин для jQ имеет API. Некоторые используют разметку (по классам и т.п.) вместо него, но суть от этого не меняется - плагин должен знать представление (класс), чтобы находить элементы. Так что иди читай. Цитата:
Цитата:
|
B~Vladi,
Ну так второй вариант вообще исключает взаимозависимость. В любом случаи что-то зависит от чего-то. |
Цитата:
|
B~Vladi,
Но они зависят от контролёра. То есть при изменение контролёра, возможно потребуется изменение модулей. |
B~Vladi,
В любом случаи независимого кода не существует. Поэтому я считаю этого надо бояться в тех случаях когда безопасность на первом плане. |
К сожалению, я вебдев и ни разу не GUI'овец, поэтому могу сказать только со своей колокольни.
Допустим, у нас есть два с виду независимых компонента: отправка формы аяксом и кастомные селекты с фенечками. Живут себе, мирно сосуществуют (каждый из них ненавязчив, ошибкоустойчив и выполняются в разных scope, ожидая событий через live). И вдруг нужно, чтобы при использовании фенечки в «псевдоселекте», срабатывала бы отправка формы. И тут те же самые два пути: можно добавить в псевдоселект вызов что-то типа « ajaxFormSend() », либо генерировать событие «jsonSuggestApply ».В первом случае получаем лишнуюю зависимость ( if (ajaxFormSend) ajaxFormSend() — так, цветочки), во втором, компонент сам отлавливает нужное событие (события) и реагирует на них.Лично мне ближе второй вариант. |
Цитата:
Фреймворк (бурж. "каркас") жестко диктует всю архитектуру приложения, во всю используя паттерны Шаблонный метод и Стратегия. То есть состоит из "заглушек", которые переопределяются приложением по мере надобности. Для примера: стандартные функции php - это библиотека. Zend Framework, CodeIgniter, CakePHP - фреймворки. Цитата:
// module #1 $('body').bind('myevent', handler1); // module #2 $('body').bind('myevent', handler2); // module #3 $('body').trigger('myevent'); // вызовутся handler1() и handler2()Разве не это требовалось? |
в моем понимании первый
путь: >--------------|@#$%%^&&**)(*&&^%%$#@@!~ и второй путь: >-------------------------------------------------------- схемы(любой символ какое-то кол-во времени) символ | - означает начало внесения изменений в логику (описанную subzey) лишняя зависимость и понеслось |
Panzermaus,
если пытаться написать на jq что-то более серьезное чем плагин в виде галереи получается страшное месиво. jq нормально годиться только на простые вещи. |
Цитата:
Цитата:
Цитата:
Цитата:
|
B~Vladi,
А почему не иметь возможность использовать такую конструкцию контролёр -> модуль -> модуль, дать возможность модулям самодополнять друг друга, такая структура сложнее другой но всё же. |
Цитата:
Во втором варианте это вполне реализуемо: модуль (источник события) -> контроллер -> (например) другой модуль -> контроллер... и так далее. Есть ещё одно удобство, которое я называю "отложенное событие". 1. Модуль получил инструкцию по событию. 2. По внутренней логике, он не может на него отреагировать, пока не наступит другое событие. Поэтому он все (но не дублирующие) события (имена) откладывает до наступления нужного (а не хранит полученные данные - вдруг не пригодятся?). 3. Когда необходимое событие наступило - реакцией будет проброс накопившихся событий в контроллер и последующее обновление (если таковое необходимо). Логика обработки событий может быть разная, главное, что она не затрагивает лишнее. |
B~Vladi,
А я бы всё равно выбрал бы первый вариант=) |
Цитата:
|
B~Vladi,
Надеюсь оно наступит не скоро=) Или когда наступит найду ещё более интересное решение) |
Цитата:
|
B~Vladi,
Ну вообще оба варианта ничего, это зависит от задачи. |
Цитата:
Все же хотел бы увидеть другие варианты. Ну или хотя бы ссылки на наиболее популярные патерны (или реализации), использующие архитектуру MVC. |
А это точно MVC называется? Вроде не похоже (хотя я только начал во всем этом разбираться). И еще по второму рисунку (тот который вроде как MVC), выглядит так, как будто модули и источники события это совсем разное. Вроде модули как раз и должны быть основными источниками?
|
Цитата:
Патерны - подход к реализации той или иной идеологии. Т.е. законченный логический вариант. То, что я описывал в первом посте - патерны. Второй вариант даже имеет своё название (как и другие), но я его не помню. Другие патерны, с которыми я знакомился, не соответствуют идеологии MVC. Поэтому второй вариант сейчас для меня наиболее симпатичен. Цитата:
Да, источник события вынесен отдельно, так как он может быть не только модулем. Если данные сообщают контроллеру о наступлении события, это не должно привязываться к конкретным модулям. Другими словами, цепочка: данные -> модуль -> контроллер не приемлема. |
Вложений: 1
Вот мое представлении о структуре Web-приложения, соответствующее идеологии MVC:
http://javascript.ru/forum/attachmen...1&d=1279640337 Т.е. у нас складывается некая иерархия. В этом топике второй вариант - третий шаг. |
[off] - не нашел такого тега
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
All Честно говоря, обcуждение MVC vs. jQuery кажется мне бессмысленным. Как, например, MVC vs. Math. У jQuery свое место - сбоку припеку. Я бы не стал ставить знак равенства между jQuery и тем кошмаром, который пишут непоймикто, используя jQuery. [/off] и покончим с этим :) B~Vladi Пришлось отдуваться за Резига, так и не ответил по существу :) Всегда стремлюсь (но не всегда успешно :() ко второму варианту. Кроме перечисленных плюсов есть еще один: облегчается повторное использование модулей. Цитата:
|
Цитата:
Цитата:
DOM — упорядоченные данные и методы для управления вообще-всем. Т.е., модель плюс данные, которыми она оперирует. CSS — отображение. В идеале, в документе каждый элемент должен содержать лишь данные о том, чем семантически он является Javascript — контроллер. Опять-таки, в идеале меняет семантическую роль элементов и их связи методами, предоставленными DOM. В итоге выходит что-то около знакомого «серверностороннего» MVC, только полувывернутого наизнанку. На сервере фронтенд — отображение, а данные, контроллер и модель — бекенд. Данные ← Модель ← Контроллер → Отображение На клиенте фронтенд — данные и отображение, бекенд — модель и контроллер.
Отображение по-прежнему не связано напрямую с данными (для любителей $(…).animate() уже придуман css transition) |
по поводу jQuery... он совместим с MVC, если использовать его как библиотеку для работы с DOM. А разница между библиотекой и фреймворком очень нечеткая, чтобы что-то определенное сказать. Т.е. на сайте сказано, что "jQuery is designed to change the way that you write JavaScript" (типа посмотрите исходники, скоро вы будете писать так :) ), так что в каком-то смысле фреймворк, но с другой стороны им можно пользоваться в дополнение к некоторой архитектуре. Кстати, насколько я помню с помощью jQuery можно генерировать события на javascript-объектах
и почему обязательно MVC? Такое впечатление, что MVC выбирается потому что круто. Зачем, например, отделять модель от вида/контроллера? Чтобы можно было их отобразить с помощью другого вида/контроллера, или чтобы вид/контроллер могли использовать данные из нескольких моделей. Зачем отделять вид от контроллера? Чтобы можно было подменить контроллер. Ты с таким сталкивался? Значит используй. Я, например, пока что нет. Кроме того, есть разные производные от MVC а зачем нужны отложенные события? Цитата:
Цитата:
что касается взаимодействия между компонентами: если это какие-то общие/повторно-используемые - лучше события, если что-то присутствующееся лишь на одной странице - зачем события непонятно. p.s. "My experience with MVC is of three extremely vague categories, which are only recognized after the fact, where one looks at a well-modularized system and places the function of each category into one of these roles, where Model pertains to state management, View to interface, and Controller to program logic. Controller ends up being the most vague of all these categories, and a satisfactory explanation is never given - mostly because MVC was designed for a very specific requirement in a specific environment, and is something of a square peg when it comes to describing architectures such as web apps or even event-driven GUI toolkits. As a high-level definition of roles, MVC has its uses, but attempting to reify it simply leads to madness, or at least frustration. Good design practice can succeed perfectly well regardless of whether it's MVC in one of its million varying guises, and indeed whether or not the designer is aware of the MVC design philosophy at all." http://www.c2.com/cgi/wiki?WhatsaControllerAnyway UPD хотя по поводу взаимодействия... события хороши когда заранее неизвестно, кому их посылать или когда не хочется связывать компоненты (причем скорее повторно-используемые). В примере subzey можно на нужной странице создать экземпляр "псевдоселекта", которому передать обработчик события использования фенечки и в этом обработчике отправлять форму. Таким образом, сам компонент не привязан к отправке формы аяксом, всего лишь обработчик события на конкретной странице |
Цитата:
Цитата:
Цитата:
Цитата:
|
Цитата:
|
Цитата:
Цитата:
Вашей точки зрения не оспариваю! Просто изложил свою трактовку MVC. Цитата:
Цитата:
Цитата:
Цитата:
Во-вторых, если не будет контроллера, то модель должна будет извещать все свои представления напрямую. Если же контроллер есть, то модель может даже не знать, сколько у нее представлений. ИМХО, если представление одно и других не предвидится, то обе причины отпадают, и в отделении контроллера от представления нет никакого смысла. |
Цитата:
Разумеется, все это только обсуждения, и никто не собирается других учить, как что делать. Но, надеюсь, каждый участник этого спора получит что-то новое для себя. |
кстати, jQuery - не первый вариант, плагины не зависят друг от друга
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
new Select({ 'change': function(){ $('#my-form').submit(); } }) Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
во-вторых, активная модель (в изначальной реализации MVC была и пассивная) как раз и должна уведомлять тех, кто на это подписался, об изменениях. Если же модель изменяется только одним контроллером, она может быть пассивной (контроллер сам знает, когда изменилась модель и сообщает об этом виду). И активная модель как раз таки не знает, сколько у нее представлений, как и пассивная впрочем. Зачем может понадобиться так разделение? Например readonly-контроллер, но это какая-то такая экзотика, имхо и давайте если продолжать, то как-то конретнее, на каких-то примерах... ну я выше говорил. А то я не уверен, что все подразумевают одно и то же под модулем, например. Я под ним понимаю все три составляющие и еще, ведь редко нужно иметь несколько видов для одних и тех же данных? Мне пока в голову пришли только разные варианты отображения файлов в Проводнике. Так вот когда это надо, можно делить, я считаю. Т.е. причина для именно такого деления есть (M/VC) Цитата:
|
Несколько приложений работают на своем объекте диспетчеризации. в общих чертах для этого требуется чтобы каждый модуль мог делегировать через сторонний диспетчер хотябы два метода bind и unbind. По опыту могу сказать то, что использует механизм диспетчеризации поддерживается удобнее. Так же большим плюсом становится возмонжость разделить модули по файлам, которые работают только со своими данными не обращаясь к сторонним объектам определенным в других модуля.
|
da_ff, можешь подробнее рассказать? Модули могут подписываться на события от конкретного источника или любого? Можешь какой-нибудь конкретный пример взаимодействия модулей привести? Ты используешь MVC?
|
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
|
Цитата:
Еще кстати для котроллера необходимо предусмотреть механизм передачи данных из объекта которые создает некое событие в его подписчиков. Вообще мое имхо, что такая событийная модель более естественна для js. Поскольку большАя часть тех операций для которых он используется имеют ассинхронную природу. |
Цитата:
Цитата:
services().get('form')->submit(); причем так даже лучше в данном случае, чем отправлять событие, потому что события это уведомления и они хороши, когда имеется сложная логика взаимодействия, когда заранее неизвестно, кого уведомлять. Но в общем-то так слишком сложно, потому что это код, специфичный для формы. Это что-то типа "не допущу, чтобы форма зависела сама от себя". Можно просто в обработчике события отправить форму, как я писал выше Цитата:
по поводу MVC, я вижу причину отделять модель от вида/контроллера, если нету четкого соответствия одна модель - один вид/контроллер. А вид с контроллером обычно слишком тесно связаны. Еще бывает смысл вынести код, который напрямую работает с DOM в отдельный класс, чтобы, если надо будет менять внешний вид, оно по-крайней мере не было перемешано с логикой работы. И в этом случае один класс (основной) - модель+контроллер, второй (работа с DOM) - контроллер+вид. По поводу первого из этих двух случаев есть смысл общаться через события, а именно уведомлять об изменениях модели если взять WPF, например, там стандартные компоненты изначально никак не связываны. Стандартный способ их связать - в коде окна, т.е. в коде окна ты ловишь события от компонентов и изменяешь/управляешь другими компонентами. Т.е. что-то типа new Select({ 'change': function(){ $('#my-form').submit(); } }) MVC там можно сделать, если нужно, но это не навязывается. А можно какое-нибудь третье решение придумать а то, что ты хочешь сделать, называется Mediator. Но для каждого паттерна есть, условия, при которых его имеет смысл применять. Он может использоваться в одной части приложения и не использоваться - в другой Цитата:
|
Цитата:
Цитата:
Цитата:
Цитата:
Модули же эти должны реализовывать логику. Представление данных, отдаваемые ими, может быть совершенно разным (один модуль на 10 сайтах). Сам модуль будет состоять из описания логики, представления и данных. Т.е. получается и внутренне разделение (внутри модуля) и внешнее (то, что будет отражено в результате). Сложно так абстрактно говорить. |
Пример структуры модуля:
<module prefix="pr" ns="urn:myModule"> <template name="tpl"> <!-- HTML --> </template> <status> tag { color:inherit; } tag.show:click { color:#f00; } </status> <code>/* JavaScript */</code> </module> Т.е. xml. Здесь модуль имеет шаблоны данных. Сами данные он берёт из xHTML кода, например: <pr:tag>data</pr:tag> Т.е. при нахождении этого элемента в состоянии (классе) show и клике по нему, будет изменятся цвет. Причем для этого нужно всего лишь описать это в состоянии (тег status) и всё. |
Цитата:
Цитата:
Цитата:
Цитата:
Начну :) Мой текущий проект (моя часть проекта) это что-то навроде автокада :) (Увы, не могу показывать недоделанный, не решаю таких вопросов :( Так что могу только рассказывать словами.) Короче редактор. Объектная модель типичного документа - связанные древовидно и как попало 100-300 объектов 15-ти разновидностей. У документа несколько представлений:
Делаю в духе MVC. Так как между объектами M (их свойствами) и элементами HTM/SVG/VML DOM (их атрибутами) нет прямого соответствия, то M - это просто набор JS-объектов, никакой связи с DOM не имеющих. M извещает C об изменениях. C знает, какие Vs видимы (управляет этим), и извещает их. C мог бы извещать Vs и без напоминаний от M, так как он знает, когда M изменилась. Однако из за низкой производительности полные перерисовки Vs недопустимы, и нужно точно знать список изменившихся объектов, и поэтому требуется извещение от M. В этом смысле M активна, но она пассивна в том смысле, что Vs сами берут из нее укзанные данные (тоже из-за производительности). Vs привязывают к событиям DOM (click, change) обработчики, которые преобразуют их в события приложения ("команды": Select, PropertyChange), попадающие в C. C, если того требует команда, вызывает методы M. Не все команды исполняются на клиенте, некоторые требуют запросов к серверу. Всем обменом ведает C, кроме этого он поддерживает undo/redo-стэк, и еще кое какой сервис для Vs вроде панелей инструментов и справки. Да, и еще! Справочная система - отдельный независимый модуль. В том смысле независимый, что пишется другим человеком, имеет собственный серверный бэкенд и используется также в других частях проекта (которые делают другие люди). Возможно будут еще какие-то модули (реклама однозначно). Такой вот пример. Короче, приложение смахивает не десктопное и делается как десктопное. Не увидел специфических для веба приемов и явлений (разве что низкая производительность), которые бы заставили отказаться от MVC или существенно его видоизменить. Но может, уважаемый All что-то посоветует? |
Часовой пояс GMT +3, время: 17:07. |