image MVC в наше время не использует только ленивый. Да и ленивый тоже, использует CMS которая реализует этот подход.
Но MVC ли это?

Архитектура именуемая MVC появилась в исследовательской лаборатории Xerox PARC, при разработке программ с графическим пользовательским интерфейсом (ГПИ). Стоит отметить что программы с ГПИ появились там же, и появившись, сразу же явили миру программирования новую проблему. Дело в том, что ГПИ, в отличие от интерфейса командной строки, отображает множество разной информации, отдельные части которой могут быть связаны и самое главное — позволяет с этой информацией взаимодействовать.

При взаимодействии пользователя с данными, они могут измениться, а это значит что могут измениться и связанные с ними данные. Например, одна и та же строка показывается в текстовом поле и в заголовке окна. Переписываем строку — заголовок должен измениться. Решение «в лоб»: когда мы понимаем что строка в текстовом поле изменилась, мы меняем строку в заголовке. Но что если одни и те же данные показываются в пяти разных местах (данные имеют пять представлений), в каждом из которых они могут измениться? Тогда придётся в каждом обработчике события изменения данных писать код, который обновляет четыре другие представления, в которых отображаются данные. Если же что-то изменится хоть в одном представлении, то вносить правки придётся во все обработчики. Код получается слишком связанным.

Для решения этой проблемы и была придумана архитектура MVC.

Суть решения:
От кода, который изменяет представление при изменении данных никуда не деться. Он должен быть. Но в одном экземпляре. Значит его надо выделить в функцию. И эту функцию вызывать из всех обработчиков. Но постойте. Слова «при изменении данных» явно дают понять, что нам неважно какое событие произошло. Значит можно вызов функций обновления представлений тоже вынести в функцию, которая будет вызываться при любом событии изменяющем данные. В итоге код обновляющий представление сам по себе, а для добавления нового представления этих же данных, достаточно добавить вызов функции в функцию изменения данных.

Программисты. а точнее исследователи из Xerox PARC любили ООП. А значит и любили то, что я называю «подъём управления» — перенос решения о вызове некоторого кода вверх по потоку управления. В основном это делается через передачу объекта, у которого потом будет вызван метод. Вместо того, чтобы делать условие в функции, можно сделать условие перед вызовом функции, в зависимости от него создать один или другой объект, и вызвать функцию, передав туда получившийся объект в виде аргумента. Что это даёт? А то, что можно будет изменить поведение функции, передавая в неё разные объекты. Сама же функция не будет изменена.

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

Это и есть классическая MV* архитектура. Насчёт контроллера ещё можно поспорить, но во всех вариантах есть данные, представления и изменение этих представлений при изменении данных.

Что в итоге: MVC решает проблему сильной связности кода, позволяя разделить модель и представления с помощью применения некоторой архитектуры.

Если искать на хабре, в гугле или яндексе, то больше всего информации находится про MVC для веб приложений. И везде говорится, что когда мы разделяем данные и представления, то это MVC. Такого определения достаточно, чтобы считать, что применение практически любых шаблонов проектирования, дающих нам расслоение системы на отдельные части это MVC.

UPD: здесь под веб приложениями я понимаю такие приложения, всё мнимое MVC которых сосредоточено на сервере. Например вот такая простая MVC система на PHP5

Но постойте. Грамотное применение ООП в любом случае нам даст систему, разделённую на слабо связанные части.
В веб приложениях вообще нет событий. Протокол HTTP обязывает нас убивать приложение после ответа на запрос, или делать вид что мы его убили. Так что единственным событием веб приложения является его запуск с некоторым набором параметров.

А если нет событий, то и представления обновлять не надо. Они и так отрисуются при создании.

В веб приложениях полезно разделять код на бизнес-логику, шаблон и контроллер, но быть может стоит называть их своими именами, а не теми, которые используются в несколько другой области программирования?

UPD: jigpuzzled указал на то что подобное отдельное название для серверной архитектуры уже существует: Action-Domain-Responder
Нужно ли для серверного MVC другое название, или же различия несущественны и никого не путают?

Проголосовало 183 человека. Воздержался 101 человек.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Комментарии (61)


  1. lair
    07.04.2015 00:54
    +1

    Вы про model2 не слышали?


    1. MadridianFox Автор
      07.04.2015 10:47

      Слышал. Согласен. Просто надо повысить процент упоминаний того что MVC это не то о чём кричат на каждом углу. Ведь никто не говорит «PHP Model2 framework», зато все ссылаются на MVС, потому что это знакомое всем слово. Точно так же как и «3D» пытаются присовокупить ко всему чему только можно, даже к зубной пасте, лишь бы лучше продавалась.


      1. lair
        07.04.2015 10:48
        +1

        Просто надо повысить процент упоминаний того что MVC это не то о чём кричат на каждом углу.

        А почему вы считаете, что ваше определение MVC — правильное? Вот Фаулер так не считает, например, его вполне удовлетворяет нынешнее применение термина MVC. И я так считаю, кстати — потому что оно отражает роли.


        1. MadridianFox Автор
          07.04.2015 11:21
          +1

          Фаулер рассматривает шаблоны проектирования применимые к разработке корпоративных информационных систем. При объяснении MVC он рассказывает про то что MVC появился при программировании на Smalltalk и про шаблон Observer. Но дальше просто притягивает за уши.
          Фаулер конечно хороший человек, но не пророк. Не стоит принимать все слова на веру, ведь иначе мы будем считать что все открытия уже совершены и дальше развиваться некуда.


          1. lair
            07.04.2015 11:25
            +1

            Ну то есть Фаулер притягивает за уши, а вы — не притягиваете. И да, как раз стремление оставить шаблон ровно таким, каким он был во времена Smalltalk и мешает развитию, а не наоборот, как вы пытаетесь доказать.

            MVC эволюционировало, став тем, что под этим понимают сейчас — точнее даже не «сейчас», а десяток лет назад: PoEAA 12 лет. Какой смысл пытаться остановить это? Текущее использование MVC в серверных приложениях не противоречит семантике.


            1. MadridianFox Автор
              07.04.2015 11:35

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


              1. lair
                07.04.2015 11:39

                И да, популярная на данный момент архитектура серверных приложений вполне может быть результатом эволюции архитектуры настольных приложений.

                А вот нет. Она является результатом самостоятельной эволюции, к которой применили уже существовавшие навыки. Несколько раз неуспешно, кстати — посмотрите, скажем, на WebForms.

                Но я говорю о том что новому веянию моды нужно новое название

                Новому? Вы серьезно?

                изучив сначала серверное MVC можно продолжить применять этот же вариант архитектуры в настольных приложениях думая, что всё правильно.

                Это проблема не имеет отношения к MVC, она имеет отношение к «взять шаблон, применить его, и думать, что все правильно». Просто надо думать.

                А в настольных приложениях сейчас доминирующие шаблоны — MVVM и MVP, а MVC там как термин практически не употребляется. Именно во избежание описанного вами эффекта.


                1. MadridianFox Автор
                  07.04.2015 11:49

                  Новому? Вы серьезно?

                  Ну относительно появления настольного MVC, серверное новее.

                  MVC эволюционировало, став тем, что под этим понимают сейчас

                  А вот нет. Она является результатом самостоятельной эволюции

                  Так имеет ли серверное MVC к настольному како-либо отношение или нет? Если Model2 развилось самостоятельно, то зачем ему чужое название?

                  Просто надо думать

                  Надо не давать повода так думать.

                  MVC там как термин практически не употребляется

                  Чтобы понять MVVM и MVP надо сначала понять MVC, потому что везде при объяснении производных архитектур сначала рассказывают как работает базовая, и потом выделяют отличия.


                  1. lair
                    07.04.2015 11:53

                    Ну относительно появления настольного MVC, серверное новее.

                    Но для современной парадигмы серверное MVC — уже устоявшийся термин.

                    Так имеет ли серверное MVC к настольному како-либо отношение или нет?

                    Конечно, имеет. Как ни странно, две независимых цепочки эволюции могут привести к одинаковому результату.

                    Надо не давать повода так думать.

                    Не выйдет. Вы не можете запретить людям думать.

                    Чтобы понять MVVM и MVP надо сначала понять MVC, потому что везде при объяснении производных архитектур сначала рассказывают как работает базовая, и потом выделяют отличия.

                    Это если считать, что MVVM и MVP — это «производные» архитектуры. А я с этим, скажем, не соглашусь.

                    Лично я считаю, что есть семейство MV*-архитектур, ключевым признаком которых является разделение модели и представления. А вот дальше есть варианты.


                    1. MadridianFox Автор
                      07.04.2015 12:13

                      Как ни странно, две независимых цепочки эволюции могут привести к одинаковому результату.
                      Вы не можете запретить людям думать.

                      Ну это уже полемика.

                      семейство MV*-архитектур, ключевым признаком которых является разделение модели и представления

                      Текст как раз намекает на то, что в определении классической MV* мало простого отделения модели от представления. Тот факт, что MV* нацелен на то чтобы обновлять представления после их создания и отрисовки при изменении модели, растворяется в объяснении архитектуры и совсем не указывается в определении.


                      1. lair
                        07.04.2015 12:19

                        Тот факт, что MV* нацелен на то чтобы обновлять представления после их создания

                        А я не считаю это критичной особенностью, отличающей MV* от… чего? И да, в stateful-системах это так, но в stateless системах — не так. Что, в stateless не может быть MV*? Но почему?


                        1. MadridianFox Автор
                          07.04.2015 12:29

                          Потому что в stateless возможно лишь одно событие — запуск с параметрами. MV* архитектура решает проблему сильной связности модели и представления при распространения событий изменения модели. В stateless этой проблемы нет, представление один раз забирает данные при создании, и это событие не зависит от того была изменена модель или нет.


                          1. lair
                            07.04.2015 12:33

                            MV* архитектура решает проблему сильной связности модели и представления при распространения событий изменения модели.

                            MV* решает проблему спагетти бизнеса и представления.

                            В stateless этой проблемы нет,

                            Есть в полный рост. Классический asp. asp.net webforrms.


                            1. MadridianFox Автор
                              07.04.2015 12:49

                              MV* решает проблему спагетти бизнеса и представления.

                              Спасибо что перевели мои же слова на IT жаргон. Видимо матёрые программисты только такими словами и оперируют.

                              Есть в полный рост

                              Проблема изменения загруженных страниц при изменении данных в БД решается другим путём. MV* тут ни при чём, разве что клиентский JS MV* фреймворк будет принимать событие с сервера и править страницу, но это уже совсем другая история.


                              1. lair
                                07.04.2015 12:51

                                Спасибо что перевели мои же слова на IT жаргон.

                                Это не IT-жаргон. И это другая проблема. Сильная связность — это не то же самое, что прямое включение.

                                Проблема изменения загруженных страниц при изменении данных в БД решается другим путём.

                                А это вообще никак не связано с тем, что я описываю.


                                1. MadridianFox Автор
                                  07.04.2015 12:51

                                  А что вы описываете?


                                  1. lair
                                    07.04.2015 12:57

                                    Если совсем грубо, то вот такое:

                                    foreach(var row in db.GetProducts())
                                    {
                                        if (user.IsAdmin || user.IsSupport || user.HasPermission(Permissions.View, row.Id))
                                            OutputProduct(row.Id, row.Name)
                                    }
                                    


                                    1. MadridianFox Автор
                                      07.04.2015 13:01

                                      Возможно мы мыслим разными категориями. Объясните в чём тут проблема и как она связана с изменением уже отрисованного представления при изменении модели?


                                      1. lair
                                        07.04.2015 13:20

                                        в чём тут проблема

                                        В отсутствии разделения обязанностей. В одном месте получение данных из БД, бизнес-логика фильтрации и собственно отрисовка, причем бизнес-логика знает про отрисовку.

                                        как она связана с изменением уже отрисованного представления при изменении модели?

                                        Никак.


                                        1. MadridianFox Автор
                                          07.04.2015 16:33

                                          Об этом я и говорю. В stateless нет изменения представлений при изменении модели. Модель и представление не связаны по управлению, значит разделить их можно просто помня, что они должны быть отделены.
                                          Вы сами же пришли к тому, что stateless не требуют решения проблемы в виде MV* архитектуры, потому что проблемы нет.
                                          Другое дело Model2 или, предложенный в другом комментарии, Action-Domain-Responder. Эта архитектура уже направляет разработчика в нужном направлении при разделении бизнес-логики и шаблона отображения данных.


                                          1. lair
                                            07.04.2015 21:17

                                            Модель и представление не связаны по управлению, значит разделить их можно просто помня, что они должны быть отделены.

                                            Вы себе противоречите. Если они не связаны, то их не надо разделять. Но они связаны — представление использует данные модели. Собственно, когда мы говорим «модель» и «представление», мы уже порождаем MV*-решение.

                                            Вы сами же пришли к тому, что stateless не требуют решения проблемы в виде MV* архитектуры, потому что проблемы нет.

                                            Я этого не говорил, вы это зачем-то додумали за меня.


                                            1. MadridianFox Автор
                                              07.04.2015 21:26

                                              Связь бывает по управлению и по данным. Так что да — они связаны и их надо разделять, но когда они связаны по управлению, сделать это сложнее.

                                              Вы сказали что ваш код никак не связан изменением уже отрисованного представления при изменении модели.

                                              Само по себе разделение приложения на слои ещё не говорит о том что приложение использует MV* архитектуру. Это всего лишь грамотное применение ООП.

                                              MV* же решает проблему отделения представления от модели когда они связаны по управлению, проще говоря — когда надо обновить представление при изменении модели.


                                              1. lair
                                                07.04.2015 21:28

                                                MV* же решает проблему отделения представления от модели когда они связаны по управлению

                                                Это ваше личное определение. Оно устарело. Извините, но Фаулеру я верю больше, чем вам.


  1. IonianWind
    07.04.2015 02:09

    Протокол HTTP обязывает нас убивать приложение после ответа на запрос, или делать вид что мы его убили. Так что единственным событием веб приложения является его запуск с некоторым набором параметров.

    А что там насчёт WebSocket?


    1. nazarpc
      07.04.2015 10:57

      Как на счёт процента сайтов, которые выдают страничку с коротеньким JS, а всё остальное работает в Full Duplex через WebSockets?
      То есть да, это возможно. И нет, на практике не видел.


    1. MadridianFox Автор
      07.04.2015 11:27

      Это JS на клиенте, а JS MVC фреймворки могут точно воспроизвести MVC архитектуру, т.к. все части архитектуры находятся в едином адресном пространстве, где издержки на их взаимодействие минимальны.


  1. jigpuzzled
    07.04.2015 04:11
    +1

    Ну это старая тема, никто и не спорит уже. Вот кстати чем на самом деле являются «MVC» фреймворки: github.com/pmjones/adr/blob/master/README.md


  1. dtestyk
    07.04.2015 05:09

    В веб приложениях вообще нет событий.
    Ох уж эти веб приложения: нет ни ajax, ни sse, ни даже addEventListener :(


    1. mayorovp
      07.04.2015 06:21
      +2

      Автор говорил про серверную часть. Там, конечно, можно использовать события — но обычно от них, наоборот, стараются уйти.


      1. dtestyk
        07.04.2015 13:55

        Даже в таком случае:
        запрос клиента на сервер — событие
        view — клиент
        controller — скрипт на сервере
        model — база данных, сессия…


        1. MadridianFox Автор
          07.04.2015 16:58
          +1

          Если View — клиент, а Model это база данных, то следуя архитектуре MVC база данных должна уведомлять браузер, чтобы тот обновил страничку.

          jigpuzzled написал очень полезный комментарий

          Вот кстати чем на самом деле являются «MVC» фреймворки: github.com/pmjones/adr/blob/master/README.md


  1. hack2root
    07.04.2015 07:06
    +1

    Во первых, фраза «В веб приложениях вообще нет событий.» не верна.

    Событие — это в данном контексте переход состяния системы из одного состояния в другое — присутствует всегда. Вы же зашли на этот сайт, чтобы написать этот пост? А какое событие произошло при этом? Вы авторизовались. Да, после того, как пользователю была создана страница, и состояние приложения передано на клиент/сервер, помнить состояние страницы не обязательно.

    Но вы путаете два разных понятия — системы без/с сохранением состояний и MVC. Полушать вас, так для реализации MVC на сервере достаточно лишь знать ООП. Тогда вопрос — а почему классический ASP.NET Web Forms 2.0, так и не стал Меккой программирования? Между тем, он реализован полностью как ООП.

    В случае с тонким клиентом, веб-приложением, состояние системы как набор параметров, сохраняеся на клиенте, однако сервер в более широком понимании, чем просто обработчик HTTP запросов, может хранить какое-то время память о вас, и о ваших постах, чтобы оптимизировать количество обращений к базе данных, слою DAL, BL и т.д, но это не имеет ровным счётом никакого отношения к тому, как реализована архитектура сервера.

    MVC потому и пользуется огромной популярностью среди серверных, в том числе JS-фреймворков, потому что он позволяет решить главную проблему — сильную связь между компонентами, M и V. Это необходимо в первую очередь для оптимизации цикла разработки и сопровождения программного кода. Например, написав на «голом» PHP код для серверной части, вы очень скоро придёте к тому, что постоянно изменяющиеся требования к системе будут усложнять код, делать его трудночитаемым и сложно сопровождаемым, и ситуация со временем будет выходить у вас из под контроля. Для анализа использования MVC в серверных framework-ов полезно почитать о них в web. Очень популярен полностью ООП-фреймворк PHP Laravel 5.

    О нём вы можете почитать тут habrahabr.ru/post/249911/, прежде чем утверждать, что "… грамотное применение ООП в любом случае нам даст систему, разделённую на слабо связанные части."

    Важно понимать, что ASP.NET Web Forms, это не ASP.NET MVC 5, или ASP.NET MVC 6. У этого фреймворка отсутсвовала поддержка MVC на уровне архитектуры системы. Хотя при разработке фреймворка, изначально, команда разработчиков рассматривала этот вариант архитектуры. Но по политичнским соображениям, и в том числе, из-за сложности разработки, отказалась от его реализации — потому что требовалась совместимость с ASP, и модель ASP.NET Web Forms, как казалось, достаточно хорошо реализовывал принципы ООП — инкапсуляция, полиморфизм, наследование. Например, был разделён код HTML и сопровождающий его код на C# на уровне модулей — то есть по разным фалам, из-за чего усложнилось написание сложного кода. Впоследствии, по этой же причине, стал популярен стиль программирования «лапша» — в результате код стало сложно не только читать, ни и сопровождать, так как отладчик мог отлаживать как V- часть, так и M- часть. Условно говоря, получалась такая «зебра» из кода View, и кода Model каждой страницы, без какого-либо управления. Привязать модель к странице не получалось, использование шаблонных серверных элементов управления выходом не стали, так как привязка осуществлялась с помошью отдельного мини языка привязки через DataItem, с использованием механизма Binding, без использования принципов, используемых на данным момент — семантическая привязка — по именованию и местоположению серверных тегов.

    Дело в том, что основным побочным эффектом от отказа от использования MVC, главной особенностью архитектуры ASP.NET Web Forms 2.0, стало то, что фреймворк буквально вынуждал разработчиков использовать ViewState, сессионные переменные, заботясь о той или иной реализации (того-же MVC) самостоятельно, что приводило к ошибкам проектирования и прктически 100% неправильному использованию ASP.NET. Это в свою очередь приводило к особенно сильной нагрузке на web-сервер, увеличению трафика и уменшению responsiveness страницы и сайта в целом. По сути, часто состояние системы (View + Model — это ViewState + SessionState) передавалось целиком от клента к серверу практически при каждом запросе.

    Вот перечисленные выше недостатки — это и есть оснвной недостаток от отказа от использования MV* в web-приложениях. Это было характерно не только для ASP.NET Web Forms 2.0, но и для большинства фреймворков, в том числе на PHP, и польностью реализующие принципы ООП, хоть и в меньшей степени.

    Еще раз, сравните Lаravel 5 и ASP.NET Web Forms 2.0. В первом реализован MVC на очень глубоком уровне, у ворого нет даже близко предствления о MVC. Более того, при разработке ASP.NET Web-Forms, разработчики архитектуры не использовали MVC в принципе.

    Что вы выберете?


    1. MadridianFox Автор
      07.04.2015 10:22

      Видимо надо было добавить сарказма в ту часть где говорится про то что применения ООП достаточно для построения системы. Я как раз считаю что этого недостаточно, и большая часть вашего комментария только подтверждает мои слова.
      JS фреймоворки бывают серверные и клиентские. Последние действительно MVC.
      Насчёт событий вы правы, но только отчасти. Логически это разные события. Но, если взять php, то при каждом запросе к серверу скрипт запускается заново и заново же создаётся модель. В этом случае нет события изменения объекта представляющего собой модель после того как графический интерфейс уже отображён. Есть вызов программы с параметрами, на основании которых выполняются манипуляции с моделью, а после, производится вставка данных модели в шаблон.
      Программы с ГПИ ведут себя иначе. Они запускаются, отрисовывают интерфейс и ожидают события взаимодействия пользователя с элементами управления. При наступлении такого события, изменение модели распространяется на уже отображённые части графического интерфейса.
      Даже если на сервере объекты модели будут жить независимо от запросов, сервер не может уведомлять клиенты об изменениях без использования JS (AJAX или WebSocket). Но в таком случае JS реализует MVC на клиентской стороне.


  1. sferrka
    07.04.2015 08:22

    В веб приложениях вообще нет событий. Протокол HTTP обязывает нас убивать приложение после ответа на запрос, или делать вид что мы его убили. Так что единственным событием веб приложения является его запуск с некоторым набором параметров.

    Весь текст основан на этих ложных и противоречивых тезисах.
    1. Можно отрабатывать события на сервере, а на клиент отдавать результат в виде скомпилированного в JS кода.
    2. Протокол HTTP — их много и работают по-разному.
    3. MVC — это архитектура приложения, к HTTP, клиенту и серверу отношения вообще никакого не имеет. Важно разделить код, а где и как его исполнять — другой вопрос. Шаблоны уже давно изоморфны. Модели и контроллеры постепенно становятся тоже, а io.js в этом очень помогает.


    1. MadridianFox Автор
      07.04.2015 10:29

      1) вы собираетесь каждый клик отправлять на сервер и получать в ответ изменения интерфейса? Не слишком ли накладно?
      2) Объясните.
      3) Везде пишут что MVC это разделение кода, но акцент на том как его разделять и чем MVC отличается от простой объектной декомпозиции забывают. Клиент и сервер тут очень важны, потому что модель живёт на сервере, а представления, которые генерируют события — на клиенте. Между сервером и клиентом длинный медный провод, который не позволяет нам отправлять все события на сервер.


      1. SerafimArts
        07.04.2015 13:03

        Если sferrka не возражает, возьму слово.
        1) Используя специально предназначенные технологии для этого — нет. Тот же Vaadin буквально построен на этом подходе.
        2) Наверное имеются ввиду Long-Polling, HTTP 2.0, WS — все эти спецификации используют перманентное сокетное соединение (в случае HTTP 2.0 — оно всё же обрывается в конце передачи данных, но всё таки).
        3) MVC — Это прежде всего архитектура и уже потом разделение. Представления не обязательно должны быть на клиенте — представления, это объект, а если он содержит html-шаблон — это уже частное применение представления. Да и вообще — тот же запрос — это уже событие, да и события не обязательно должны инициализироваться клиентом (от взаимодействия с интерфейсом).


        1. MadridianFox Автор
          07.04.2015 16:51

          1) допустим
          2) Long-Polling, HTTP 2.0, WS не являются основой того что называется PHP MVC Framework. Упор там делается на построение Action-Domain-Responder архитекутуры, а живое общение с сервером бывает приплетается для большей динамики.
          3) Возможность заменить представление передавая разные объекты классов производных от некоторого класса View ещё не является MVC. MVC решает проблему обновления представления при изменении модели и больше подходит к варианту когда есть много графических представлений, где при работе с одним представлением надо сразу же обновлять все другие. Когда одно представление выводит данные в графический интерфейс, а другое — в файл, тут не требуется распространять изменения моментально, скорее по явному требованию пользователя надо пропустить данные через Responder, который выдаст файл.


          1. sferrka
            07.04.2015 17:35

            2) Long-Polling, HTTP 2.0, WS не являются основой того что называется PHP MVC Framework. Упор там делается на построение Action-Domain-Responder архитекутуры, а живое общение с сервером бывает приплетается для большей динамики.

            Суть в том, что нет никакой разницы оборвать соединение или нет, это технические нюансы, главное, что состояние, на самом деле, сохраняется (именно в PHP MVC) — сессии, токены форм, http-авторизация и т.д. И уже второй запрос к серверу будет не responder, а именно событийного характера — например, сохранить измененные данные текущего пользователя. Точно так же это будет работать и в обратную сторону — в плане подписки на изменение модели. То, что технически это будет прерывистая подписка (скажем так, вызов контроллера, отвечающего за подписку по таймеру) не меняет сути.


            1. MadridianFox Автор
              07.04.2015 17:48

              Но архитектура сервера здесь не играет никакой роли. Можно какую угодно лапшу развести на сервере, система клиент-сервер в целом будет обмениваться событиями.
              Я же говорю о том, что архитектура применяемая на серверной стороне и горда именуемая MVC на самом деле таковой не является и называться должна иначе, т.к. решает другую проблему.


              1. sferrka
                07.04.2015 18:01

                Я же говорю о том, что архитектура применяемая на серверной стороне и горда именуемая MVC на самом деле таковой не является и называться должна иначе, т.к. решает другую проблему.

                Тогда могу сказать, что такой архитектуры и не существует. То, о чем вы пишите не предполагает наличие клиента, все должно работать только на сервере. И это точно не про PHP. Сам язык создавался для клиент-серверных приложений и я не знаю ни 1 фреймворка, который не предполагает знание о клиенте. Еще раз обращаю ваше внимание на сохранение состояния ими всеми.


                1. MadridianFox Автор
                  07.04.2015 20:50

                  То о чём я пишу никак не называется, но можно сказать что это не DHTML. Может быть я открою страшную тайну, но http это stateless протокол общения клиента с сервером, где в качестве клиента выступает браузер. Браузер может работать без JS. PHP фреймворки чаще всего ориентированы на генерацию html на сервере.

                  Протокол HTTP называется stateless не потому что он вообще не сохраняет состояние, а потому что он это состояние не держит постоянно в памяти. Данные в БД, они в БД. Сессия это файл на сервере. Токены форм — они в формах в браузере. Всё это позволяет не обращать внимания на непостоянность пользователя.
                  Платой за это является то, что сервер не может инициировать передачу данных, он только отвечает.
                  Чтобы обойти это ограничение есть Long-Polling, WS и постоянно повторяемые AJAX запросы.

                  Но без JS кода на клиентской стороне это невозможно. А PHP MVC фреймворки по определению реализуют всю MVC архитектуру на сервере. По крайней мере создателям кажется что они реализуют именно MVC.


                  1. SerafimArts
                    07.04.2015 20:57

                    Вы не поверите, но Symfony или Laravel можно с таким же успехом использовать для работы сквозь WS, совершенно не меняя код именно этой части приложения, ни контроллеров, ни вьюх, ни уж тем более моделей.

                    Да и реализовать какое-нибудь прикладное приложение тоже можно, совершенно не меняя подход, разве что ловить события аннотациями будет удобнее (мы опустим тот момент, что MVVM всё же в этом случае удобнее).


                    1. MadridianFox Автор
                      07.04.2015 21:09

                      Тот факт, что некоторые фреймворки можно без особых усилий перевести на другие принципы общения с клиентом говорит о том что они хорошо спроектированы и Domain у них отделён от Responder'a.
                      Я же говорю о том, что эта прекрасная архитектура — совсем не то MVC, которое используется в настольных приложениях.


                      1. SerafimArts
                        07.04.2015 22:23

                        Давайте вы ответите на вопрос что значит «та», ибо пока что я наблюдаю только возражения вида «серверные контроллеры не отлавливают нажатия клавиатуры», которые уже 1000 раз были опровергнуты (т.к. отлов клавиатуры — это не часть архитектуры, а часть бизнес-логики).


                        1. MadridianFox Автор
                          07.04.2015 22:37

                          Это кто тут 1000 раз сказал что серверные контроллеры таки отлавливают нажатия клавиш?
                          То MVC я описал в тексте статьи и 999 раз в комментариях сделал акцент на том, что обычно в определении того MVC упоминают только отделение представления от модели, а надо указывать ещё и то, как получившаяся структура реагирует на события. Ведь именно для этого существует диаграмма последовательости. Одной только диаграммы классов мало чтобы показать как ведёт себя тот или иной шаблон.

                          Поведение MVC в настольном приложении и в серверном (именно HTTP, без динамики) отличаются. Не верите? Постройте диаграммы последовательности для обоих случаев.

                          Я лишь хочу сказать что разница есть, и возможно, для снижения количества недоразумений при изучении этих похожих архитектур, стоит их по разному называть.


                          1. sferrka
                            08.04.2015 07:27

                            У вас остался один аргумент — HTTP разрывает соединение. HTTP к теме поста относится чуть более, чем никак. MVC — это не HTTP. PHP MVC — это не HTTP. Да, они все имеют HTTP-адаптеры, но это связано исключительно с техническими ограничениями браузеров и, как уже было сказано 100 раз и вы это подтвердили, технические возможности меняются, а некоторые фреймворки можно без особых усилий дописывают адаптеры к новым протоколам.


                            1. MadridianFox Автор
                              08.04.2015 11:07

                              Мы с вами ушли в сторону от темы поста. Пост о том, что есть архитектура MVC придуманная для программ с ГПИ и сейчас при разработке веб приложений многие серверную архитектуру называют точно так же. Я не рассматриваю случаи где активно используются ресурсы клиента, для динамического общения клиента с сервером. Только варианты, когда общение с сервером происходит через отправку форм и переходы по ссылкам. В этих случаях весь код приложения исполняется на сервере. И вот архитектура этого кода отличается от архитектуры чисто настольного приложения. Эти две популярные архитектуры имеют очень похожую структуру, но разное поведение, которое обуславливается событиями, которые распространяются по приложению с момента его запуска до момента завершения его работы. А разница в событиях есть, её нам даёт протокол HTTP.
                              Посмотрите внимательно на пост, в его конце есть опрос, целью которого является выяснение — считают ли люди эти две архитектуры настолько разными, что им нужны разные названия.


                              1. sferrka
                                08.04.2015 12:59

                                Я вам еще раз повторяю, что описываемых вами архитектур не существует, с чем вы боретесь, с собственными фантазиями? Я написала, что даже чистый PHP — это не генератор HTML, а уже про фреймворки и говорить не стоит.

                                Видимо, чтобы разобраться в ваших страхах нужна конкретика, какой PHP-фреймворк (название) вы считаете не MVC?

                                Максимум, ваш страх относится к stateless API — но это вообще к MVC отношения не имеет.


                              1. sferrka
                                08.04.2015 14:07
                                -1

                                И еще, задача контроллера не обмен напрямую данными между M и V.
                                Контроллер — это собственная структура данных, которая не относится к предметной области.
                                Это искусственно организованная среда, которая нужна как раз для того, чтобы мы могли не меняя модель — структурировать данные в представлении в удобном виде тысячами способов.

                                Пример:
                                есть класс в модели, House, у него есть свойство rooms, это массив Room. У каждой Room есть куча свойств.

                                Далее, есть куча представлений — внешнее API, мобильное приложение, сайт. Каждый из них хочет разные данные от Room и House. Например, API хочет, чтобы его класс House содержал поле — количество комнат с ванной.
                                /house/4
                                {«roomsWIthBathroom»:5}
                                Всем остальным это поле не нужно.

                                Вот, чтобы модель не содержала в себе все поля для тысяч представлений и нужен контроллер и MVC.

                                Где-то можно обойтись и MVVM структурой, которую вы и описываете в посте.

                                Мне больше всего понравилось описание MVC в книге Марка Симана Dependency Injection in .NET. Рекомендую.


              1. SerafimArts
                07.04.2015 18:05

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

                Больше отличий я не наблюдаю.


                1. MadridianFox Автор
                  07.04.2015 20:56

                  Отличие в том, что в классическом MVC представление с моделью связаны по управлению, в серверной архитектуре представление по управлению связано с контроллером.
                  В MVC при возникновении события, его ловит контроллер, передаёт модели, а та в свою очередь передаёт на все свои представления.
                  В серверной архитектуре контроллер так же получает событие, передаёт его модели и после этого передаёт его же представлению.


                  1. SerafimArts
                    07.04.2015 22:34

                    Теперь я наконец понял, что Вы хотели донести.

                    Desktop MVC: controller -> model -> view
                    Server MVC: controller -> model -> controller -> view

                    Да, возможно это так, но это, как показала практика — довольно плохой подход связывать данные с вьюхой без посредника (контроллера, репозитория, не важно), лучше пропускать всё сквозь контроллер, и запрос и ответ, нежели отвечать из модели. Но это не мешает строить приложения именно отвечая из модели. Благо и в Symfony, и в Laravel — ничто не мешает это делать (в последнем с помощью view-composer, view-share и проч.). Да и в десктопных приложениях точно так же.


                    1. MadridianFox Автор
                      07.04.2015 22:44

                      Скорее
                      Server MVC: controller -> model => controller -> view
                      Где толстая стрелка — это связь по данным, а тонкая — по управлению. Уж что что, а модель контроллер никогда вызывать не должна.


                      1. SerafimArts
                        07.04.2015 22:54

                        Модель и не вызывает ничего, модель вообще ничего не знает ни о чём (у меня просто стрелочки кривовато нарисованы наверное). Это контроллер запрашивает нужные данные из моделей и формирует ответ (если ответ нужен).


                        1. bromzh
                          07.04.2015 23:42

                          Так это уже получается MVP. В классическом MVC контроллер обрабатывает события, поступающие от View и вызывает методы моделей. А модель рассылает оповещения (но подписываться на них должны сами View).


                          1. SerafimArts
                            08.04.2015 01:31

                            Для личного самообразования: Судя по всему MVP почти что и есть MVC, за исключением того, что модели отправляют события, а не вьюшки на них подписываются. Если я конечно правильно понял картиночку на википедии ru.wikipedia.org/wiki/Model-View-Controller

                            Верно?


                            1. bromzh
                              08.04.2015 02:19

                              Нет, модели отправляют события в MVC. Модель предоставляет интерфейс для добавления слушателей на свои события. А подписан на них кто-то или нет — модели всё равно, она ничего не знает, кто и как будет использовать её данные дальше. Когда данные изменились, модель оповещает всех, кто подписался на её события. Паттерн Observer.

                              В MVP же прямой коммуникации между M и V нет, между ними посредник — P. Модель обычно пассивная и предоставляет только интерфейсы для манипуляции данными (сохранение, получение). V перенаправляет команды, поступившие от пользователя к P. P как-то на них реагирует, например, запрашивает данные у M. M выполняет полученные действия, отдаёт данные (если необходимо) обратно в P, P подготавливает их для отображения и отсылает к V.
                              Там получается такая схема: V<->P->M


                              1. SerafimArts
                                08.04.2015 05:46

                                Ну вот я и говорю, что получается на сервере MVP, а не MVC, хоть и называется вторым. Т.к. описанию MVP полностью соответствует.


      1. mukizu
        07.04.2015 13:09

        1) Vaadin и иже с ним, например так и работают вроде


  1. igor_suhorukov
    08.04.2015 00:16

    Грамотное применение ООП в любом случае нам даст систему, разделённую на слабо связанные части.

    Сомнительное утверждение. Как раз недавно описывал зачем нужно аспектно-ориентированное программирование, когда существует ООП


  1. MadridianFox Автор
    08.04.2015 10:42

    Не в обиду вам будет сказано, но основы АОП никто не описывает. Те на кого снизошло озарение, пишут о том какая это хорошая штука, но таких же понятных как по ООП материалов по АОП в открытом доступе нет или настолько мало что они тонут в океане восторженных упоминаний об АОП.
    Даже вы пишете про AspectJ — частный случай для одного языка.