Как стать автором
Обновить

Комментарии 57

Извините, а зачем вы путаете MVC с реализацией бизнес-логики? MVC — это способ реализации GUI, а бизнес-логика от GUI традиционно должна отделяться.
Скорее Вы что-то путаете. MVC — это не про GUI, это как раз про разделение бизнес-логики и представления.
PoEAA: «Splits user interface interaction into three distinct roles.» (выделение мое). Там же, каталог: «Web Presentation Patterns: Model View Controller...»

Так что MVC — это паттерн организации интерфейса. В нем выделяется компонент, который отвечает за взаимодействие с бизнес-слоем, но сам этот бизнес-слой не реализует.
GUI — Graphical user interface. (выделение мое)
И что вы этим хотели сказать?
то, что интерфейс не обязательно графический

А не очень важно, графический он, или консольный, или голосовой — все равно это все presentation layer.

MVC изначально был разработан именно для GUI
Вам никто не поверит…

Проблему не-масштабируемости дизайна и всего что с ним связано вообще мало кто понимает :)
Как я вас понимаю :)
Я хочу терминологически поддержать lair. Всё-таки MVC используется в презентационной части. И Controller обеспечивает логику поведения интерфейса, а не бизнес-логику приложения.
Если мы имеем выделенный сервер бизнес-логики со своим API, то для его реализации паттерн MVC не используется.
А уже к нему подвлючается Web-Frontend на базе MVC или клиент тоже на MVC или даже MVVM
«Любую проблему в архитектуре ПО можно решить введением дополнительного слоя. Кроме слишком большого количества этих слоев».

Это я к тому, что во многих случаях вся программа — это MVC-приложение и СУБД. И ничего плохого в этом нет.
В таких случаях в ней и бизнес-логики нет особо. Ну да, типичный data entry, чего стесняться.
Посыл статьи, похоже, о том, как организовать и упорядочить множество представлений, когда они так и норовят влезть друг другу в контроллеры в случаях, когда есть всякие многошаговые визарды или сложное многуровневое редактирование — это уже абстракцция повыше, чем MVC и на уровне архитектуры все таки это логика бизнес процесса.

В таком случае есть риск создать спагетти на уровне вьюшек и контроллеров. Сам если честно еле вкурил авторскую траву, началось с «MVC недостаточно, но он спас весь мир от спагетти», внезпно откуда ни возьмись модули, и тут опа — ктото куда то лезет и это плохо почему то когда система поставляется множеству пользователей (а не когда много модулей)

Медитация над картинками помогла, но логика изложения, как ни странно, похожа на то самое пресловутое спагетти. Конкретный пример бы здорово помог — A, B, C всегда плохие имена для переменных.
Представления не должны лезть в контроллеры, точка. Это же просто.
Они и не лезут, статья не о том что происходит между компонентами внутри _одного_ набора MVC, а о том, как сделать так чтобы несколько наборов не создали кашу из связей и что одного лишь MVC тут недостаточно

Представьте страничку на шаге 19 которая позволяет вам изменить данные (адрес, данные кредитки или координаты вашей бабушки) которые вы ввели на шаге 1, 2, или 4.

Без рутового контроллера придется завязываться в контроллер конкретного шага — это и есть сильная связь в данном случае (даже если это просто POST на другой контроллер — вьюшка из шага 19 завязана на формат данных которй принимает контроллер на шаге 1 (редактирующий возможно более полную версию модели)

Представьте страничку на шаге 19 которая позволяет вам изменить данные (адрес, данные кредитки или координаты вашей бабушки) которые вы ввели на шаге 1, 2, или 4.

Убить проектировщика UX.

Без рутового контроллера придется завязываться в контроллер конкретного шага

Убить проектировщика UI. Это должен быть один контроллер.
Ну по вашей логике я сегодня должен был утром идти в офис O2 и положить их отдел разработки

Да, именно, должен быть один контроллер — в случе бизнес процесса это должен быть 1 (одна штука) рутовый контроллер процесса. На последней картинке это и показано.

В больших или интегрированных системах контроллеры могут вообще лежать в отдельных частях системы, которые даже могут поставляться по отдельности или быть опциональными, или даже написанными на другом языке.
Ну по вашей логике я сегодня должен был утром идти в офис O2 и положить их отдел разработки

Иногда эти мысли полезны, да.

Да, именно, должен быть один контроллер — в случе бизнес процесса это должен быть 1 (одна штука) рутовый контроллер процесса. На последней картинке это и показано.

Вот только не должно быть в одном (связанном!) процессе нескольких «модулей».
Легко например в OSGI, Eclipse — живой пример
DI контейнер + интерфейс. И связанные контролерам не должны знать ничего кроме интерфейса. А вобще очень похоже что вы пытаетесь решить проблему композиции компонентов и навигации. В .NET для таких вещей раньше исспользовали SCSF, сейчас исспользуют Prism, но очень уж тяжолая вещь. MVVM и инфрастуктура WPF/Silverlight/WinRT позволяют максимально изолировать зависимости.
Событийная модель это с легкостью переваривает. Контроллер генерирует события, на которые подписано N других контроллеров. И в контроллере-генераторе вообще не нужно знать о том, как его события будут обрабатываться другими.
На самом деле в статье я хотел показать разные степени связанности между MVC и бизнес-логикой. К чему это приводит, и как можно вынести бизнес-логику из UI.
MVC вообще говорит, что вся бизнес-логика находится в Model.
И увы, Model в MVC не раскрыта. Например, можно с MVC использовать DCI, которое, как раз приоткрывает завесу, как упорядочить Model.

Однако, проблематика вашего поста, говорит о построении блочного продукта, с возможностью гибкого изменения workflow при наименьших трудозатратах. Но, я не понимаю, чем root controller поможет продукту(см мой комментарий ниже)
НЛО прилетело и опубликовало эту надпись здесь
Полезно, плюсую, только важно понимать, что root controller делает вам такую же каку, как и глобальные переменные в коде — важно уточнить, что root controller должен быть один на бизнесс процесс. Даже если он физически один, а процессы описываются в XML или где еще, — логически важно понимать что это разные контроллеры отдельных процессов.
Я бы даже сказал, что root-контроллер это тоже MVC (поверх другого MVC) с присущими ему недостатками из статьи :))
Честно говоря, для меня тема вообще не раскрыта.
Есть много блочных проектов, с которыми невозможно работать.

Пример из жизни:
Eсть CMS + Управление проектами.
CMS — это один блок. Управление проектами — второй.
При этом, заказчик хочет привязать проект к клиенту, но т.к. это различные блоки, сделать это невозможно.

Многие инструменты должны присутствовать в представлении, что бы workflow был простым и понятным.
Скорее всего я не понял того, что предлагается в статье или же такой подход вообще не решает проблемы.
Но, в обоих случаях, мне кажется, тема не раскрыта.
Пример из жизни:
Eсть CMS + Управление проектами.
CMS — это один блок. Управление проектами — второй.
При этом, заказчик хочет привязать проект к клиенту, но т.к. это различные блоки, сделать это невозможно.


В статье я пытался рассказать, как можно организовать архитектуру внутри одного приложения.
В вашем же случае, вы хотите связать функционал двух приложений (или независимых модулей).

Для решения таких задач существуют отдельные фреймворки, например, Spring Integration для Java. Где создаётся интеграционный посредник, который связывает функционал двух или более приложений или модулей системы.

Честно говоря я не очень понял, причём же здесь MVC и в чём он виноват…
На самом деле MVC виноват в том, что за деталями не видно сути вещей.

Думая в терминах Модели, Представления, Контроллера очень легко связать разные модули системы в тесносплетённый клубок. Тем самым, повторное использование модулей будет затруднено и сама система превратится в один большой монолитный модуль.

Разве это вина MVC? Точно так же можно сказать про что угодно — да хоть про то же ООП :) Отключая мозг, можно такого нажечь…

Всё-равно, реально очень сложно уловить вашу мысль.

Но здесь кроется коварство использования MVC шаблона. Как показано на изображении ниже, велик соблазн ссылаться напрямую с представления (View) модуля 'A' на контроллер (Controller) модуля 'B', с модуля 'B' на модуль 'C', с модуля 'C' на модуль 'D'.

А как по-другому? Если текущий экран предполагает, что с него я могу попасть только в Б или С, то хоть убейся — от этих ссылок ты никуда не уйдёшь, это часть интерфейса. Другое дело, что их можно генерировать автоматом на основе общего workflow. Но это же всё-равно не избавляет от ссылок на другие контроллеры. И плюс, в том же вебе, подобные элементы навигации оборачиваются в partial, на самом деле представляют из себя лишь URL'ы и в итоге никакой жёсткой привязки модулей друг к другу.
Если текущий экран предполагает, что с него я могу попасть только в Б или С, то хоть убейся — от этих ссылок ты никуда не уйдёшь, это часть интерфейса.


С текущего экрана можно попасть на экраны Б или С, если в root контроллер отправлять не прямую связь с модулем Б или С, а событие. Например в визардах есть кнопка Next. Она может отправлять событие «next», которое, согласно конфигурации в отдельном файле, скажет системе показать пользователю экран Б. При этом все экраны могут отправлять события «next», «prev», «cancel», а порядок их переходов определять в конфигурации.

Пример кода:
<wizard initial="A">               
    <view id="A">
        <on event="next" to="B"/>
    </view>

    <view id="B" >
        <on event="next" to="C"/>
        <on event="previous" to="A"/>
    </view>

    <view id="C">
        <on event="previous" to="B"/>
        <on event="finish" to="finish"/>
    </view>
    
    <on event="cancel" to="cancel"/>

    <final id="finish" />
    <final id="cancel" />
</wizard>

UIP, CAB и так далее. Пробовали. Не взлетает. Сложность конфигурации пробивает потолок поддерживаемости на первом же добавленном компоненте.

Ну не должен, не должен визард быть за пределами одного компонента.
Здесь визард, как пример.

Сложно в комментариях показать все варианты использования конфигураций приложения.

За реализацией, например, Lexaden Web Flow (LWF) стоит не просто Statemachine, а Statechart с реализацией иерахий состояний. Плюс реализовано наследование и полиморфизм для них, что облегчает повторное использование частей конфигурации.

Например, бизнес логика переходов CRUD компонентов определена отдельно и повторно используется во вмногих модулях системы.

Примеры конфигураций для разных компонентов можно посмотреть на Enterprise Sampler.
Что такое «бизнес-логика переходов CRUD-компонентов»? Почему ее нужно повторно использовать?

Ничего не понимаю.
А не получиться так что вы утоните в собственных конфигурационных файлах и все программирование перейдет туда, а для реализации какой нить нетривиальной штуки, придется городить костыли?
Да, частично программирование уйдёт туда. К этому стремятся многие приверженцы Business Process Management (BPM) систем.

Но BPM годится только для организации бизнес процессов между приложениями. И их использование внутри одной системы не очень оправдано.

Плюс BPM системы основаны на спецификациях, что налагает некоторые ограничения. Например, они перегружены разными деталями привязки к данным, создания переменных и д.р. вещами, которые усложняют конфигурацию.

Почему бы не вынести бизнес процессы внутри одного приложения в конфигурацию? Это позволит легче понимать бизнес процессы не программистам, например, бизнес или функциональным аналитикам, продукт или проджект менеджерам.

Они смогут тогда общаться на одном общем языке. Не об этом ли они мечтают?
Почему бы не вынести бизнес процессы внутри одного приложения в конфигурацию?

Потому что стоимость поддержки растет. В итоге вы получаете Inner platform syndrome.
Полностью поддерживаю.
Когда начинаем выносить бизнес-логику в конфигурацию, получаем тонны головной боли:
— Тяжелая отладка
— Сложность разворачивание продукта
— Затраты на поддержание документации по настройкам
В моем личном рейтинге ненависти к конфигурируемым системам лидирует пункт «разбираемся, что там наконфигурил заказчик прямо в продуктиве».
Открываем Википедию, видим там: «Концепция MVC была описана в 1979 году». Какой-то длинноватый тупик, уже более 30 лет туда идём.
Или я вас не понял, и заголовок статьи — это не про тупик, а про то, что он устарел. Но последний случай — это всё равно, что сказать «закон Ньютона устарел», или что-то подобное. А ведь он не устарел, просто человечество раздвинуло рамки знаний, и проникло туда, где он не работает.
На самом деле все MV-x (MVC, MVVM, MVP и т.д.) шаблоны в чистом виде не подходят для разработки больших приложений, и порой даже для не больших кросс-платформенных приложений. По сути это все равно что использовать Code Behaind в WinForms, WPF и т.п. К примеру в своих проектах там где испольузую моно, ядро приложения (общий код) пишу классической трехзвенкой а дальше для работы с UI для Windows Phone, Win 8 и Single Page Web клиент использую шаблон MVVM (VM работает с LogicLayer). А для Android, iOS и классической web-интерфейс на MVC (Controller работает с LogicLayer).

Я планировал сделать очередную статью на эту тему на каком нибудь простом кроссплатформенном (Android, iOS, WP, W8, Web) примере вроде простого списка покупок или списка задач с бекендом, но не уверен что это будет кому нибудь интересно.
Ну говорить, что MV* не подходит для больших проектов это как говорить, что колеса подходят для велосипедов, но для танков не подходят. В танках тоже есть колеса, хотя и не сразу видно.

Пишите обязательно, будет интересно
Потому и уточнил «в чистом виде» потому как для танка тоже колеса в чистом виде не подошли )
Windows Workflow Foundation имеет какое-то отношение к этим web-flow?
Нет.
А что-нибудь подобное для ASP.Net не подскажете?
Если речь идет о MVC то конечно — есть готовый фреймворк ASP.NET MVC который поставляется прямо в студии. Но вы наверняка спрашивали про WF — конечно же WF можно без проблем использовать и в веб приложениях. Просто обычно WF достаточно медленная штука и если вам нужна высокая производительность то WF, мягко говоря, надо использовать очень осторожно.
Предлагаю не переживать по поводу недостатков сырого MVC, а почитать про патерны специально предназначенные для изоляции модулей.
«Бузина в огороде завяла, так что Киеву капец..». Хотя внимание заголовок привлек, 100%. ;-)

Микроуточнение: Более общее решение — IoC, схема с центральным контроллером и выносом логики в workflow/BPM engine — распространенные частные случаи. Первый — весьма сомнительный, второй — очень популярный.
НЛО прилетело и опубликовало эту надпись здесь
А причем здесь MVC? М.б. речь скорее о некоем IoC в виде некоего модуля, который говорит V, куда далее, а не хардкодит в неё.

Имхо всё-таки уровни и цели попутаны.

ps: Вот, даже выше товарищи уже подсказали.
ну а теперь разверни внутренности этого «root controller» и увидишь, что он состоит из субственно рутового контроллера, который вызывает другие контроллеры, а также из рутовой вьюхи, которая собирает разрозненные вьюхи в одну. то есть пресловутый mvc никуда не девается, просто вьюхи и контроллеры выстраиваются в иерархию.

другое дело, что mvc на клиент-серверную архитектуру вообще не проецируется. точно также как объекты херово ложатся в реляционную базу. ибо пользователь взаимодействует исключительно со вьюхой, а она уже толкает контроллеры, чтобы те обновили её саму. в вебе же всё взаимодействие клиента и сервера происходит через контроллер, который (в случае апи) может вообще никак не обрабатывать выходные данные и просто сериализовывать модель.
Facepalm, в статье рассказали про Front Controller.
именно :)
Если кому интересно, то вышло проложение этой статьи: Навигация: вариант реализации для корпоративного приложения с более подробными деталями реализации описанного решения на примере Lexaden Web Flow и Vaadin.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории