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

В то время как все больше и больше фронтенд-разработчиков перенимают подходы с однонаправленной архитектурой, возникает вопрос — есть ли будущее у классического MVC? Чтобы понять, как мы дошли до такого вопроса, давайте немного проанализируем эволюцию архитектуры фронтенда.

За последние 4 года я видел множество веб-проектов и потратил немало времени на разработку архитектуры фронтенда и интегрирование различных фреймворков.

До 2010 года JavaScript (язык программирования, на котором был написан jQuery) использовался, в основном, для манипуляций с DOM и прикручивания дополнительной логики, оживляющей веб-приложения. Разработчиков не особо волновала архитектура, поскольку штуки вроде revealing module pattern вполне справлялись с задачей структурирования кодовой базы.

Дискуссии на тему архитектуры фронтенда в сравнении с бэкендом фактически начались с развитием концепции single page application (в конце 2010 года) и с растущей популярностью фреймворков типа Backbone и Knockout.

Поскольку тогда это было новшеством, разработчики этих фреймворков вынуждены были искать вдохновения на стороне, так что они обратились к уже хорошо устоявшимся практикам, применяемым на серверной стороне. А к тому моменту все популярные серверные фреймворки в том или ином виде реализовывали классический MVC (Model?—?View?—?Controller), также известный как MV* из-за различных вариаций.

Когда React.js впервые был представлен как библиотека рендеринга, многие принялись его высмеивать за интуитивно непонятные манипуляции с HTML в JavaScript. Но разработчики упустили из вида важнейший вклад, который принес миру React, — компонентно-ориентированную архитектуру. React не изобрел компонентный подход, но перенес идею на новый уровень.

Этот главный прорыв в архитектуре проглядели даже в Facebook, когда они анонсировали React как «V в MVC».

Примечание: меня до сих пор преследуют кошмары после ревью проектов, в которых одновременно использовались React и Angular 1.x.

2015 год стал поворотным для сознания разработчиков — от привычного MVC мы перешли к однонаправленным архитектурам и потокам данных, унаследованным от Flux и функционального реактивного программирования, с помощью таких инструментов, как Redux или RxJS.

Когда же для MVC все пошло не так?


MVC до сих пор остается, пожалуй, лучшим способом разработки серверной части приложений. Работать с фреймворками вроде Rails или Django — одно удовольствие.

Корень проблемы в том, что принципы и декомпозиции, которые MVC представляет на сервере, не такие же, как на клиенте.

Связь контроллер-представление


Диаграмма ниже показывает, как контроллер и представление взаимодействуют на сервере. Между ними всего две точки взаимодействия, обе они пересекают границу между сервером и клиентом.

Когда мы переносим MVC на клиент, начинаются проблемы. Контроллеры напоминают то, что мы называем «code-behind». Контроллер сильно зависит от представления. В большинстве реализаций фреймворков он даже создается представлением (как в случае с, например, ng-controller в Angular).

Кроме этого, если вспомнить принцип единственной ответственности, это прямое нарушение правил. Код клиентского контроллера в определенной степени имеет дело и с обработкой событий, и с бизнес-логикой.

Толстые модели


Вспомните, какие типы данных вы храните в модели на клиентской стороне.

С одной стороны, у вас есть данные типа users и products, представляющие состояние приложения. С другой стороны, вам приходится хранить состояние интерфейса — что-нибудь вроде showTab или selectedValue.

Так же как и контроллер, модель нарушает принцип единственной ответственности, поскольку у вас нет отдельных способов управления состоянием приложения и состоянием интерфейса.

Так где в этой модели место компонентам?


Компоненты представляют из себя: представление + обработка событий + состояние интерфейса.

Диаграмма ниже показывает как фактически разделить стандартную MVC модель, чтобы получить компоненты. Выше линии осталось именно то, что пытается решить Flux: управление состоянием приложения и бизнес-логикой.

Одновременно с популярностью React и компонентно-ориентированной архитектуры мы также увидели растущую популярность однонаправленной архитектуры для управления состоянием приложения.

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

Но это больше не история про один React. В Angular 2 можно увидеть точно такие же подходы, хотя и с различными вариантами управления состоянием (например, ngrx/store).

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

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

Что же нам готовит будущее?


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

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

Будет ли такой тип архитектуры лучшим решением через пять лет? Вполне возможно, что да. Но опять же, нет ничего определенного.

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

От переводчика


Я фулл-стек разработчик в отделе фронтенда Tutu.ru, опыт работы 5 лет. Ранее писала на C#, cейчас пишу на JavaScript/Node.js и PHP.

В Tutu.ru фронтенд проделал немалый путь — от подсветки маршрута электрички при наведении (кто не знает, Электрички — наш самый старый проект) до полноценного SPA (single page application) в новом разделе Автобусы.

До 2013 года у нас не было отдела фронтенд-разработки, хотя JavaScript, конечно же, использовался. Все разработчики были фулл-стек мастерами, но «выходцами» из бэкенда. Поэтому вполне логично, что когда клиентская кодовая база усложнилась настолько, что нужно было ее как-то структурировать, разработчики попытались перенести привычный и родной MVC с бэкенда на фронтенд.

Это было лучше, чем ничего, но впоследствии мы столкнулись с проблемами, хорошо описанными в статье. В 2014 году мы постепенно начали переходить на однонаправленные архитектуры и теперь MVC у нас живет только на бэкенде (и в легаси-фронтенде, на правах почетного ветерана).
Поделиться с друзьями
-->

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


  1. yelbota
    15.02.2017 10:30
    +5

    MVC умер, да здравствует MVC!


  1. KIVagant
    15.02.2017 10:57
    +4

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


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


    1. VolCh
      15.02.2017 11:25
      +8

      Если в MVC на бэкенде у вас монструозные контроллеры, то у вас неправильный mvc. Что там может быть монструзного? Бизнес-логика в модели, рендеринг во вью. Монструозными они получаются когда в них пихают логику относящуюся не к ним.


      1. Pinsky
        15.02.2017 12:03
        +2

        А еще некоторые люди сложную бизнес логику выносят в слой Service. В модели остается только бизнес логика связанная непосредственно с данными сущностями.

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


        1. VolCh
          15.02.2017 12:12

          Модель — это вся бизнес-логика, «размазанная» по сущностям и сервисам. Модель должна быть как можно более толстой, включать всю бизнес-логику. В идеале спрятанная от контроллера и модели за фасад/адаптер, но этим можно пренебречь на практике.


          1. Pinsky
            15.02.2017 12:18
            +1

            Классы моделей на 2-3к строк — повод задуматься не слишком ли много на себя берет один класс. И зачастую код вполне себе хорошо делится на несколько классов.

            Излишняя толстота любого из слоев — это плохо. Но бизнес логике место именно в моделях. Это да. Контроллеры должны быть максимально тонкими.


            1. VolCh
              15.02.2017 12:26
              +2

              Да ради бога, хоть на 100 классов поделить. Главное, чтобы бизнес-логика оставалась в модели, чтобы не протекала в контролерры и вью, а как делить всю отвественность модели между классами сущностей и сервисов в её составе, дело уже десятое в рамках MVC.


              1. Pinsky
                15.02.2017 12:27

                С т.з. бэкенда View должен быть, по возможности, исключительно и полностью тупым.


            1. rumkin
              16.02.2017 14:43

              Бизнес логика должна лежать в сервисах, а модели лишь проецируют данные приложения в БД.


              1. Pinsky
                16.02.2017 15:17

                Не вся. Та, что относится исключительно к данным модели может находится в модели.
                И да, модели не обязаны быть построены из БД.

                У меня они могут строиться из конфигурационных файлов и много чего еще.


              1. VolCh
                16.02.2017 16:17

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


              1. sentyaev
                16.02.2017 22:20

                Раньше был Transaction Script, теперь то о чем вы говорите называется Anemic Model.
                Да, подход рабочий. Хорош ли он, с этим можно поспорить.


          1. fr33z3
            15.02.2017 13:04
            +2

            Модель это не бизнес логика — не путайте. Модель может делать что-то сама — например изменять собственное состояние. Но зачастую мы хотим совершать какие-то действия над моделью, а еще более зачастую хотим менять состояние одной модели в зависимости от состояния другой и так далее. Вот это уже и есть бизнес логика. То, что делает приложение, как говорится «valuable».


            1. VolCh
              15.02.2017 13:25
              +2

              По-моему, это вы путаете модель с классами сущностей в этой модели.


              1. sentyaev
                15.02.2017 22:08

                Немного дополню, в DDD бизнес логика как раз в сущьностях. А модель предметной области — это по сути и есть сам Problem Domain.


                1. VolCh
                  16.02.2017 07:36

                  В сущностях и сервисах, если сложно отнести логику к какой-то отдельной сущности.


            1. sentyaev
              15.02.2017 22:11

              Тут весь вопрос, что вы имеете ввиду говоря «модель» и в каком контексте.
              Если мы говорим о DDD, то Модель это Problem Domain.
              А бизнес логика Модели в Сущьностях (Entity).
              Ну и конечно не все так просто.


          1. begor
            15.02.2017 13:17

            Пока, Single Responsibility.


            1. VolCh
              15.02.2017 13:26

              Почему пока? Каждый класс в модели (сущность, объект-значение, сервис и т. д.) делает одну вещь и делает её хорошо. :)


            1. sentyaev
              16.02.2017 22:24

              Если говорить об MVC, то M может быть чем угодно это не DTO.


      1. T-362
        15.02.2017 12:19

        Мне это напоминает, падрон, Agile, «если оно не работает вы его неправильно используете», при этом сотни статей с взаимоисключающими вариантами как его правильно использовать.
        MVC не серебряная пуля, если какие-то суровые проблемы — можно и посмотреть на другие шаблоны.


        1. Pinsky
          15.02.2017 12:25
          +2

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


          1. KIVagant
            18.02.2017 23:39

            В имплементации MVC во всех популярных фреймворках, контроллеры — это то самое «что-то не так». Потому что у них нет одной ясной задачи и каждый лепит что умеет.


            1. Pinsky
              20.02.2017 11:51

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

              Это примерно, как уроки по GoLang — меня от изучения него очень долго отталкивал стиль написания кода в примерах. Потом сам для себя решил, что если в примере экономят на буквах(в именах переменных, например), то никто не мешает мне на нем писать нормально.


              1. KIVagant
                20.02.2017 12:03
                -1

                Я работал с разными образцами. Дело в самом паттерне — он допускает слишком много трактовок, что создаёт почву для плохого кода.


      1. vanxant
        15.02.2017 13:17
        +3

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

        Идея в том, что не нужно смешивать в модели задачи хранения и обработки.

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


        1. VasilioRuzanni
          15.02.2017 13:23

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

          Так это и будут голые данные, зачем тут еще что-то «генерить»? (кроме как чисто какие-либо объекты ORM или вроде того — но это уже детали реализации).

          Придерживаюсь точки зрения, что модель — это данные плюс поведение (бизнес-логика), а не только данные.


          1. vanxant
            15.02.2017 16:22

            Генерить классы под конкретный орм из SQL, WSDL или какой-то другой схемы.


        1. VolCh
          15.02.2017 13:29

          Сервисы бизнес-логики неотъемлемая часть модели. А хранение данных не отвественность модели.


          1. vanxant
            15.02.2017 16:28

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


            1. VolCh
              15.02.2017 16:48

              С точки зрения программы, она создаёт модель в памяти из (как правило) части хранилища, обращается к модели и, если надо, сохраняет её изменения в хранилище. Модель — это не независимый процесс, это объекты создаваемые программой.


              1. vanxant
                15.02.2017 19:27

                Я не знаю, какие программы вы пишете, но видимо не сильно сложнее helloworld-а.
                В реальном мире структура моделей вам приходит извне (от железа, от другого софта, в т.ч. унаследованного, из стандартов, от гос. органов и пр.), а правила их обработки (бизнес-логика) — тоже извне, но из другого.
                Примеры.
                В бизнесе: модели заданы альбомом бухгалтерских документов, утвержденным минфином, бизнес-логика — приказами налоговой, которая любит каждый год в них чего-нибудь менять.
                В инженерке: модели заданы а) софтом типа солидворкса или акада, файлы которого нужно уметь не только читать, но и корректно писать б) промышленными железками с их крайне тупыми форматами. «Бизнес-логика» приходит в виде ТЗ, ТУ, ОСТов и т.д. и т.п., а также стопки увесистых книжек про матан, сопромат и прочую жуть.
                В геймдизе: форматы моделей заданы видеокартами и используемой либой. Да, однородные координаты, да, только вот такой формат текстур. «Бизнес-логика» придумывается на ходу геймдизом и меняется семь раз в неделю.
                Вы конечно можете запихать в модель «годовой баланс» правила его сведения, или в модель космического корабля — правила расчёта урона его лазеров в зависимости от цели… но это очень плохая идея.


                1. Metus
                  15.02.2017 20:14
                  +4

                  Почему-то многие считают, что модель — это классы в папочке models.
                  Модель — это не класс и не объект. M в MVC — это самое абстрактное определение модели из существующих.
                  Модель — это источники данных и правила их обработки, а работа приложения — моделирование.


                  Объект, хранящий космический корабль — часть модели. Расчёт лазеров в зависимости от цели — тоже часть модели. Какой-то там сервис для обработки объектов — тоже часть модели.


                  1. KIVagant
                    18.02.2017 23:44

                    В этом вообще проблема паттерна. Он обо всём и ни о чём конкретно, что подразумевает десятки трактовок и сотни имплементаций.


                1. VolCh
                  16.02.2017 07:44

                  И что, программа работает с альбомами (бумажными) минфина и приказами налоговой? Нет, она создаёт в памяти некую модель бизнес-данных по этим альбомам, вызывает некое действие по этим приказам и сохраняет результат. «Годовой баланс» лишь часть всей модели учёта организации, а модель учёта лишь часть всей модели деятельности организации. И, конечно, правила сведения годового баланса будет находиться в модели баланса, а не в модели розничной торговли или планирования отпусков.


    1. rraderio
      15.02.2017 16:31

      middleware pipeline

      Можете расказать как устраняются старые монструозные контроллеры?


      1. KIVagant
        18.02.2017 23:42

        Они заменяются на цепочку из middleware, например как здесь. Запрос и ответ просто передаётся «из рук в руки», пока кто-то не решает вернуть его или он не доходит до последнего получателя.

        В результате то, что можно ещё назвать контроллером по аналогии с ранее используемыми в Symfony 2 или ZF2, выглядит гораздо тоньше и является просто ещё одним шагом в цепочке логики.


        1. lair
          19.02.2017 00:44

          Подождите-подождите, но у вас же мидлварь выполняет только инфраструктурные задачи, нет?


          1. KIVagant
            19.02.2017 00:45

            Не уверен, что понял ваш вопрос. Что значит «инфраструктурные»?


            1. lair
              19.02.2017 00:47

              Аутентификация, авторизация, сериализация/десериализация.


              1. KIVagant
                19.02.2017 01:12

                Нет, не только. Вся логика проекта построена на таких слоях.


                1. lair
                  19.02.2017 02:21

                  Тогда как вы разделяете домен, UI и отображение?


        1. TheShock
          19.02.2017 09:16

          Они заменяются на цепочку из middleware, например как здесь

          Если вы вынесли код из контроллера в отдельный файл, как мусорку — этот код никуда не делся. Зачем логику разных частей сбрасывать в одном файле? Те мидлвары, которые вы указали — глубокие детали реализации и в роутах им точно не место. А если вынести в контроллер (где им и место), то будет самая обычная композиция.


  1. fetis26
    15.02.2017 10:59

    Примечание: меня до сих пор преследуют кошмары после ревью проектов, в которых одновременно использовались React и Angular 1.x.

    А можно поподробнее про этот момент? Что вызывало такие кошмары.
    Мы сейчас подумываем дать возможность интегрировать в свои проекты реакт-компоненты. Не скорости ради, как было в Ангулар 1, а скорее для более широкого выбора возможностей при разработке отдельных частей.


    1. 0dmin
      15.02.2017 12:03
      +2

      Это перевод статьи. Думаю что можно узнать подробности у самого автора
      https://medium.freecodecamp.com/is-mvc-dead-for-the-frontend-35b4d1fe39ec


  1. http3
    15.02.2017 11:04
    +14

    А мне пофиг.
    Да здравствует jQuery! :)


  1. Aries_ua
    15.02.2017 11:16
    +1

    Странно что у вас MVC вызывает негатив. Если правильно структурировать, то и на фронтенде все будет красиво. Со своего опыта могу сказать что модульная архитектура очень выручает. Приятно читать код, который у тебя разбит на разделы

    • js
    • sass
    • templates


    В свою очередь js разбит на пакеты и модули, к примеру

    • menu / header
    • dashboard / owner


    А каждый модуль состоит из router, handlers, views etc

    PS handler — это аналог контроллера

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


    1. ympyst
      15.02.2017 12:29
      +4

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

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


      1. TheShock
        16.02.2017 04:40
        +1

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

        Почему вы говорите так, словно это взаимоисключающие вещи? «Колбаса не вызывает у меня негатива, но хлеб значительно важнее».


    1. Iqorek
      15.02.2017 13:30
      +3

      Для больших проектов разбиение на js,sass, template это зло, потом тяжело найти части, я разбиваю по модулям/компонентам, каждый со своими скриптами, стилями и ресурсами. Ну а webpack уже все в одно место собирает. Так можно сосредоточиться на одном маленьком и независимом модуле/компоненте и не нужно искать его запчасти в разных местах.


      1. Aries_ua
        15.02.2017 21:58

        Templates and sass сожержат такую же структуру — один в один как и модули для JS. В самом начале, когда это проектировал, мне показалось это удобным. И в принципе так оно и есть. По крайней мере ни от кого из девелоперов не слышал, что это плохо.


        1. VolCh
          16.02.2017 07:45

          Речь о том, чтобы на верхнем уровне выделять модуль, компонент системы, например customer, а туда складывать и js, и sass, и всё что ещё может понадобиться компонент.


        1. Iqorek
          16.02.2017 13:17
          +1

          Скорей всего такое разделение пошло от какого нибудь «hello world» проекта, который стал потом референсным шаблоном для всех html проектов. Когда в проекте 10 файлов, это ок, для микро проекта структура проекта, так же как и архитектура (вам не нужен архитектор, чтобы построить шалаш ;)) вообще не важна, можно как угодно раскидать файлы по папкам или вообще обойтись без них и все будет работать. Когда же количество файлов переваливает за сотню, то с одной стороны все сложено по полочкам, аккуратно и красиво, но искать связанные файлы становится очень трудно. Это не делает работу невозможной, но тратиться больше времени, которое уходит на поиск точно такой же папки только в другой ветке, вместо того, чтобы нашел папку компоненты и там все лежит все, я даже юнит тесты туда кидаю, что относится к этой компоненте и ничего, что к ней не относится. Это получается такой микропроект компоненты, внутри обычного, который кстати потом можно относительно легко выделить в отдельный проект, если он вдруг разросся. Попробуйте, это удобно.


          1. Aries_ua
            16.02.2017 13:40

            В начале так и было, но потом возникли небольшие проблемы с сборкой для гранта. И тогда я перенес структуру в нынешнее состояние. Уже и грант почил и сборка на галп перешла, сейчас вот планирую на вебпак перейти, а структура все так же неизменна. Надо покрутить вебпак (уже вторая версия) может внесу изменения.


          1. justboris
            16.02.2017 15:26
            +1

            Абсолютно согласен. Если templates положить отдельно от js, то иногда получаются странные переходы.
            Из гипотетического src/js/app/users/UserView.js нужно делать такой require, чтобы получить соотвествующий шаблон


            require('../../../templates/app/users/UserTemplate.hbs')

            А если потом понадобится переместить js-файл, то нужно обязательно не забыть и про шаблон.


            1. Aries_ua
              16.02.2017 16:48

              Эта проблема решается довольно просто. У меня используется шаблонизатор от моззилы nunjucksJS.Он умеет делать прекомпиляцию на сервере. После чего все шаблоны модуля вкомпиливаются в модуль. Дальше уже никакие импорты не нужны, как так по умолчанию шаблоны уже с модулем. И конечно, из-за прекомпиляции, скорость работы с шаблонами очень высокая. Рендер шаблона такой же как и у реакта, а иногда и обгоняет.

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

              По поводу копирования — редкий кейс. Так как основные модули собраны в core и запаблишены в локальный NPM репозитарий. Другие проекты, которые разрабатываются просто инсталят себе модули. Таким путем достигается и версионность и поддержка.


  1. VolCh
    15.02.2017 11:20
    +5

    Странно, на бэкенде как раз классический mvc не используется обычно, а предназначен классический как раз для динамических UI, где либо вью подписывается на изменения в модели, либо контроллер сообщает вью необходимость перерендериться. Как по мне, то react/redux как раз ложатся на классический MVC, где реакт — вью, редакс — модель, а реакт-редакс, контроллер, обеспечивающий реакцию вью на изменения модели.


    1. boolive
      15.02.2017 12:56
      +2

      К тому же MVC был придуман для оконных программ с событийным поведением пользователя — тот же фронт.


    1. TheShock
      16.02.2017 04:46
      +2

      Как по мне, то react/redux как раз ложатся на классический MVC, где реакт — вью, редакс — модель, а реакт-редакс, контроллер, обеспечивающий реакцию вью на изменения модели.

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

      My presentational components:
      — Are concerned with how things look.

      My container components:
      — Are concerned with how things work.


      Ничего не напоминает? Поняли теперь как современные разработчики по-модному называют вьюху и контроллер? Presentational and Container!


  1. indestructable
    15.02.2017 13:28
    +3

    А разве архитектура с однонаправленными потоками — это не MVC? Ведь именно MVC постулировала зависимости в одном направлении.


    На примере Реакта:


    Model -> application state,
    View -> JSX
    Controller -> Reducer + Middleware, разделение на логику перехода по состояниям и логику взаимодействия с "внешним миром".


  1. lair
    15.02.2017 13:36
    +4

    А к тому моменту все популярные серверные фреймворки в том или ином виде реализовывали классический MVC

    Дальше можно не читать, в принципе. На сервере никогда не было классического MVC, на сервере был Model 2 и его наследники. Для классического MVC нужны события, которые в парадигме запрос-ответ сделать сложновато.


    1. heleo
      15.02.2017 14:47

      Model 2 это то, что называется JSP model 2 architecture?


      1. lair
        15.02.2017 14:48

        Да.


    1. rousgg
      15.02.2017 15:23
      +1

      про MVC была недавно хорошая обзорная статья
      https://habrahabr.ru/post/321050/

      MVC может быть активным/пассивным, поэтому событий в нем может и не быть.

      А так я согласен с предыдущим комментарием. Однонаправленный поток — этот тот же самый MVC. Ничего нового не придумали.

      Что на самом деле произошло?
      1. работа со стейтом в одном месте помогает уменьшить разные сайд эффекты из-за мутабельности данных
      2. отказались от точечной перерисовки — да какой смысл это делать, когда браузеры стали невероятно быстрыми, а большая часть компонентов очень маленькие. Бери и перерисовывай все целиком и никто ничего и не заметит.
      3. мы снова получили событийную модель, на которую очень ругались в бекбоне. Говорили о том, как это сложно поддерживать, непонятно что происходит и тд. Но теперь она стала всем проще и понятнее. На самом деле мы просто уже привыкли к событиям и натерпелись связанного лапшекода и трудноподдерживаемого состояния. По факту чем меньше ваш компонент, тем проще подписываться на события, которые могут на него повлиять. Все это же самое можно делать сейчас и в бекбоне.


      1. jbubsk
        15.02.2017 21:13
        -1

        активный/пассивный — Вы точно MVC обсуждаете?


      1. staticlab
        15.02.2017 21:23

        отказались от точечной перерисовки — да какой смысл это делать, когда браузеры стали невероятно быстрыми, а большая часть компонентов очень маленькие. Бери и перерисовывай все целиком и никто ничего и не заметит.

        Перерисовывал весь как раз-таки Бэкбон: вставлял данные в шаблон, получал строку разметки и обновлял innerHTML. В Реакте же манипуляция щадящая — неизменившуюся часть элементов он и не трогает.


    1. pawlo16
      15.02.2017 20:09
      -1

      == Для классического MVC нужны события,


      откуда вы это взяли?


      == которые в парадигме запрос-ответ сделать сложновато.


      причём здесь "запрос-ответ"?


      1. lair
        15.02.2017 20:48

        откуда вы это взяли?

        Из описания. Observer построен на событиях, даже если их нет явно в языке.


        причём здесь "запрос-ответ"?

        При том, что HTTP — это запрос-ответ. Соответственно, веб-сервера (как минимум преимущественно) — запрос-ответ. Соответственно, серверные MVC-фреймворки (в подавляющем большинстве) — запрос-ответ.


        1. pawlo16
          15.02.2017 21:41
          -1

          Это фантазии мастера выдуманных архитектур, прославившегося циничной эксплуатацией тупости ООП-шников.


          Вебсокеты есть везде и давно. В отличие от "классического MVC"


          1. lair
            15.02.2017 21:50

            Это фантазии мастера выдуманных архитектур, прославившегося циничной эксплуатацией тупости ООП-шников.

            Says who, простите?


            Вебсокеты есть везде и давно. В отличие от "классического MVC"

            Ну так покажите мне (веб-)серверный MVC-фреймворк на вебсокетах.


            1. pawlo16
              15.02.2017 22:47
              -1

              тот, кто читал эту статью, а так же ряд других работ данного автора.


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


              1. lair
                15.02.2017 22:50

                тот, кто читал эту статью, а так же ряд других работ данного автора.

                Я тоже читал, и не говорю такого. Мнение на мнение.


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

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


                1. pawlo16
                  16.02.2017 07:49
                  -1

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


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


                  1. lair
                    16.02.2017 11:40
                    +1

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

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


                    В любом уважающем себя серверном фреймворке есть вебсокеты.

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


                    Следовательно там есть события.

                    Нет, следовательно, там есть возможность реализовать события.


                    Вот я и прошу вас показать этот "классический MVC"

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


                    Ну и да, примера ради: в ASP.net MVC нет вебсокетов, нет событий (кроме жизненного цикла самой инфраструктуры) и нет классического MVC — там типичный Model 2.


                    1. pawlo16
                      16.02.2017 12:30
                      -3

                      Здесь пойнт не в субъективности, а в оценке автора, на которого вы сослались как на авторитет — если он не создал ничего практически ценного, то какие есть основания у кого либо вообще принимать его мнение во внимание?


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

                      зависит от задач конечно. Для SPA серверный фреймворк, в котором нельзя безболезненно прикрутить вебсокеты следует выкинуть на помойку. и не надо пожалуйста рассказывать, что это субъективное мнение


                      Нет, следовательно, там есть возможность реализовать события.

                      вебсокет без реализации событий лишён смысла


                      Я и говорю: ошибка в логике

                      Вообще-то вы предложили мне доказать негативно сформулированный тезис, логически следующий из ваших утверждений "Ну так покажите мне (веб-)серверный MVC-фреймворк на вебсокетах", что не логично. На что я естественно предложил вам сделать это самому.


                      в ASP.net MVC нет вебсокетов

                      В контексте разговора существенно, что там есть возможность использовать вебсокеты, пусть даже через костыли. Это больше говорит о качестве инструментов .net/C#, чем о предмете разговора — многое, из того что нужно, отсутствует, зато дофига лишнего


                      нет классического MVC

                      Не надо выдавать ваши с Фаулером домыслы о том, что есть классический MVC, за стандартные общепринятые понятия


                      1. lair
                        16.02.2017 12:34
                        +1

                        Здесь пойнт не в субъективности, а в оценке автора, на которого вы сослались как на авторитет — если он не создал ничего практически ценного, то какие есть основания у кого либо вообще принимать его мнение во внимание?

                        Ваша оценка "не создал ничего практически ценного" — субъективна. Поэтому вы, конечно, можете не принимать его мнение во внимание. А я могу не принимать во внимание ваше мнение.


                        Для SPA серверный фреймворк, в котором нельзя безболезненно прикрутить вебсокеты следует выкинуть на помойку.

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


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

                        Есть, но там все равно останется Model 2.


                        Не надо выдавать ваши с Фаулером домыслы о том, что есть классический MVC, за стандартные общепринятые понятия

                        Осталось понять, кто же определяет понятие "классический MVC".


                        (мне все-таки интересно, с чем именно вы спорите — с используемым мной определением классического MVC, или с тем, что классический MVC в этом определении не использовался в серверных фреймворках?)


                        1. pawlo16
                          16.02.2017 13:40
                          -1

                          Ваша оценка "не создал ничего практически ценного" — субъективна.

                          Ваше игнорирование аргументации не прокатывает, я выше написал почему это объективно


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

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


                          Осталось понять, кто же определяет понятие "классический MVC".
                          мне все-таки интересно, с чем именно вы спорите

                          никакого "классического MVC" не существует, концепция MVC слишком размытая и абстрактная. Определения, область применения и пределы распространения не ясны. Если обобщать всё, что про это известно, так это будет скорее RoR, Django и ASP.net mvc со всем комплексом их уродства, нежели чем фантазии ООПшных теоретиков. Веб фрэймворки дают опыт обеих знаков, Фаулер и иже с ним не дают ничего, а потому идут далеко. То у них UML, то Rich Model, то DDD, то какое-то особенно правильное "классическое" понимание MVC то еще какая-то хрень.


                          1. lair
                            16.02.2017 13:45
                            +1

                            я выше написал почему это объективно

                            Nope. Нет объективного способа оценить "вклад в индустрию". Вы, видимо, не считаете Refactoring и PoEAA "вкладом", я — считаю, "и вместе им не сойтись".


                            никакого "классического MVC" не существует

                            Ну вот видите. Значит, и на сервере его не существует. С чем спорили-то?


                            Если обобщать всё, что про это известно, так это будет скорее RoR, Django и ASP.net mvc со всем комплексом их уродства

                            И на основании чего вы делаете такой вывод?


                            Определения, область применения и пределы распространения не ясны.

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


                            То у них UML, то Rich Model, то DDD, то какое-то особенно правильное "классическое" понимание MVC

                            … а кто-то где-то говорил, что оно "особенно правильное"?


                            1. pawlo16
                              17.02.2017 16:16
                              -1

                              Нет объективного способа оценить "вклад в индустрию"

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


                              И на основании чего вы делаете такой вывод?

                              Из того, что имеет хоть какой-то практический смысл, это наиболее близко к изначальной концепции MVC Реенскауга


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

                              Можно игнорировать, можно не — это не имеет значения, как и для всего, что не подтверждено практикой


                              1. lair
                                17.02.2017 16:20

                                можно тысячи бесспорных примеров вклада в индустрию привести

                                Попробуйте. Но в любом случае они не будут подтверждать то, что любой другой вклад в индустрию можно объективно оценить.


                                Из того, что имеет хоть какой-то практический смысл, это наиболее близко к изначальной концепции MVC Реенскауга

                                О, то есть вы все-таки сравниваете с Реенскаугом. Остается вопрос (а) как именно вы сравниваете и (б) как вы определяете, что имеет практический смысл, а что нет.


                                Но не суть, вы же уже сказали, что "классического MVC нет".


                                Можно игнорировать, можно не — это не имеет значения, как и для всего, что не подтверждено практикой

                                В таком случае этот спор изначально бессмысленнен. Я и не сомневался.


                          1. retran
                            16.02.2017 16:10

                            RoR, Django и ASP.net mvc


                            А ничего, что все три фреймворка построены на паттернах из PoEAA?
                            Ну, наверное, все-таки стоит ознакомиться с источником перед тем как его критиковать.


                            1. pawlo16
                              16.02.2017 19:33
                              -1

                              Вообще всё построено на паттернах. Elm Architecture, Erlang/OTP например — квинтэссенция применения всевозможных паттернов. В то же время ничего не построено на паттернах. Такая вот особенность применения гуманитарных знаний, к которым относятся паттерны, в технических областях. Знакомится со всеми книжками по паттернам нет смысла. Можно прочитать один раз одну книжку чисто чтобы словарь понимать, и забыть про ООП-литературу насовсем.


                              1. lair
                                16.02.2017 22:05

                                Знакомится со всеми книжками по паттернам нет смысла. Можно прочитать один раз одну книжку чисто чтобы словарь понимать, и забыть про ООП-литературу насовсем.

                                Мимими, книжки по паттернам в ООП-литературу записали.


                              1. retran
                                17.02.2017 13:49

                                Продолжайте в том же духе. Серьезно.


                      1. VolCh
                        16.02.2017 12:55
                        +1

                        Для SPA серверный фреймворк, в котором нельзя безболезненно прикрутить вебсокеты следует выкинуть на помойку. и не надо пожалуйста рассказывать, что это субъективное мнение

                        Конечно субъективное, причём и неверное. Термин SPA появился в начале 2000-х, вебсокеты — через 10 лет. 10 лет надо было выкидывать фреймворки и писать всё с ноля?


                        1. pawlo16
                          16.02.2017 14:58
                          -1

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


                          1. VolCh
                            16.02.2017 19:54
                            +1

                            Я не вижу никакого указание на время до или после вебсокетов вообще. Вижу только абсолютное утверждение: нет вебсокетов — на помойку.


  1. staticlab
    15.02.2017 15:31
    +3

    Но разработчики упустили из вида важнейший вклад, который принес миру React, — компонентно-ориентированную архитектуру. React не изобрел компонентный подход, но перенес идею на новый уровень.

    Чем же, по-вашему концепция реактового компонента принципиально отличается от директивы из первого Ангуляра или даже компонента jQuery?


    Более того, реализации однонаправленного потока как раз-таки разрушают компонентную архитектуру, деинкапсулируя состояние компонентов.


  1. Jaromir
    15.02.2017 15:39
    +3

    > Будет ли такой тип архитектуры лучшим решением через пять лет?

    Через 5 лет будут веб компоненты. Встроят ли в них реакт? К сожалению, да


  1. Riim
    15.02.2017 18:51
    +1

    Блин, да откуда берутся эти люди, утверждающие, что MVC не однонаправленный? Разница между MVC и Flux лишь в том, как взаимодействуют контроллер и модель. В MVC контроллер напрямую ковыряется в модели, в Flux он лишь генерит событие с данными, а модель уже сама решает как эти данные разложить по себе. Где тут изменение потока?


    1. staticlab
      15.02.2017 21:18
      +3

      Мне кажется, что всё дело в пиаре Фейсбука, и в том хайпе, с которым он продвигал свой Flux.


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


      Программисты в основной массе — молодёжь, а молодёжи свойственны революционные настроения. Вот и с Реактом так же получилось. Типичные компоненты, новизна только в синтаксисе (PHP-way, ага :) и в способе обновления DOM-элементов. Причём писать на голом Реакте оказалось не по зубам даже его авторам, что и сподвигло их сделать свой фреймворк, объединив паттерны MVC, State Machine (в Redux это особенно хорошо видно) и Event Loop. Но толпа уже лезет на баррикады: "Землю рабочим, фабрики крестьянам!"


    1. vintage
      20.02.2017 06:35
      +1

      Меня больше удивляет термин "однонаправленный поток данных", который не может быть однонаправленным в принципе, если речь идёт о пользовательских интерфейсах. События от пользователя — такой же поток данных, как и события от сервера.


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


      Так что это не "однонаправленный поток данных", а "контролируемый лишь в одном направлении поток данных". И придуман он был не потому, что это какая-то вся из себя классная архитектура, где корневой контроллер (который обозвали actions) знает о каждой кнопке на странице, а потому, что сначала запилили кривой шаблонизатор (реакт), не способный полноценно абстрагировать внешние компоненты, от внутренних, а потом стали думать, как бы прикрутить к нему обратный поток. И ничего умнее не придумали, как забить на все слои, стучаться напрямую в корневой и копипастить эти бесконечные редьюсеры+константы+экшены на каждый чих.


      1. VolCh
        20.02.2017 09:30

        Меня больше удивляет термин "однонаправленный поток данных", который не может быть однонаправленным в принципе, если речь идёт о пользовательских интерфейсах. События от пользователя — такой же поток данных, как и события от сервера.

        В том-то и суть, что на входе приложения события (независимо от источника: события UI, сервера, всякие таймеры и интервалы, иногда даже какие-то аппаратные события), изменяющие состояние приложения, а на выходе отрендеренный интерфейс. Из рендерера события не генерируются, состояние не изменяется. Всё что умеет делать приложение в устоявшемся режиме — обрабатывать внешние события, сначала реагируя на них изменением состояния, а потом реагируя на изменение состояния ререндирингом интерфейса.


        1. vintage
          20.02.2017 09:46

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


          1. VolCh
            20.02.2017 10:09

            Нет никакого обратного потока данных в рамках приложения. Пользователь взаимодействует с элементом UI в целом вне приложения, равно как и сервер и т. п., событие генерирует платформа (например, браузер) и сообщает о нём приложению. Обработчик события в приложении изменяет состояние приложения, и в ответ на изменение состояния приложение ререндерит интерфейс средствами платформы и на этом всё. Один поток: событие платформы -> обработчик в приложении -> изменения состояние приложения -> рендерер приложения -> рендерер платформы. Какие-то события платформы могут не изменять состояния приложения, какие-то обрабатываться самой платформой, какие-то изменять состояние, но это изменение не нуждается в рендеринге, что-то отрендеренное приложением, может не рендериться платформой (например часть окна за пределами вьюпорта), в общем поток обрубается раньше чем доходит до непосредственного аппаратного рендеринга, но вспять он не обращается, единственный способ как бы повернуть его вспять — инициировать новое событие через платформу или сэмулировать его. Часто, конечно, технически есть способы, например, изменить
            состояние из рендерера приложения, минуя основной поток, но это грубый выход за рамки архитектуры, которые не должен пройти ревью.


            1. vintage
              20.02.2017 10:38

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

              Ага, через libastral.


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


              1. VolCh
                20.02.2017 10:54

                Через платформу, тот же браузер, которая частью приложения не является.


                Никто не мешает вам разбить свое приложение на компоненты, которые будут практически являться мини-приложениями в рамках того же флоу изнутри, и как бы элементами платформы снаружи. Классический пример для реакта — компоненты форм. Изнутри компонент выглядит как полноценное приложение со своим богатым состоянием, возможно даже со своими потоками взаимодействия с внешним миром, о которых приложение в целом не знает, а снаружи практически ничем не отличается от контрола платформы типа одиночного инпута, кроме разве того, что его value не скаляр, а объект со сколь угодно сложной структурой.


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


                1. vintage
                  20.02.2017 12:06

                  Только вот какие состояния шарить решать может лишь компонент-владелец. Поэтому для обеспечения максимальной гибкости из компонента выносятся вообще все состояния, делая их "чистыми". Кривая архитектура порождает кривые решения. Для сравнения, в $mol любой компонент является вещью в себе, но компонент владелец через биндинги может управлять любым его состоянием.


                  1. VolCh
                    20.02.2017 13:56

                    Только вот какие состояния шарить решать может лишь компонент-владелец.

                    И это логично. Хуже нет, когда компонент "думает": "это мои данные", а по факту их меняют все кому не лень, его даже не уведомляя.


                    Поэтому для обеспечения максимальной гибкости из компонента выносятся вообще все состояния, делая их "чистыми"

                    Есть такой подход, но где-то на пути от компонента до глобального неймспейса (включительно) ставится контейнер с единственным/основным назначением держать стейт и передавать нужные его части в нижележащие компоненты через свойства, иногда через контекст. Это может быть как выделенныей компонент, так и какой-нибудь HOC.


                1. staticlab
                  20.02.2017 13:26

                  Вот это не совсем правда: сложный компонент потребует для себя отдельного места в общем сторе и, соответственно, отдельного редьюсера. В общепринятом подходе, когда редьюсеры объединяются через combineReducers, вроде бы состояние компонента относительно инкапсулировано. Но, во-первых, до этих данных всё-таки можно достучаться как с целью чтения, так и записи; во-вторых, компонент должен знать точку монтирования своего редьюсера (так, документация к redux-form говорит, что редьюсер крайне желательно монтировать именно по ключу form и менять этот ключ не рекомендуется); в-третьих, если нам понадобятся одновременно два или несколько таких компонентов, то это или должен предусматривать компонент изначально, или потребуются костыли вроде одновременного размещения нескольких редьюсеров с разными ключами; в-четвёртых, потенциально переиспользуемый компонент должен упредить возможный конфликт типов событий, для чего, как правило, используют тот или иной префикс в строке типа; наконец, в-пятых, компонент должен или рассчитывать на некоторое требуемое множество middlewares, или не использовать их совсем. В итоге — никакой реальной инкапсуляции и переиспользуемости.


                  1. VolCh
                    20.02.2017 13:59

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


                    1. staticlab
                      20.02.2017 14:29

                      А какая реальная альтернатива? Flux?


                      1. VolCh
                        20.02.2017 15:12

                        Альтернатив много, выбирать нужно по требованиям и просто вкусу даже, если по требованиям особой разницы нет. Я сейчас вовсю юзаю обсерваблы MobX и как сторы глобальных или близких к тому состояний, и как стейт отдельного компонента. Главный плюс субъективный — легко применимы обычные принципы ООП с вкраплениями ФП в рамках декомпозиции по DDD.


                        1. staticlab
                          21.02.2017 15:08

                          А цепочка обсерваблов MobX не возвращает ли нас к multidirection flow?


                          1. VolCh
                            21.02.2017 15:49

                            По умолчанию нет, хотя постараться можно.


                  1. indestructable
                    20.02.2017 14:31
                    +1

                    Подходы к декомпозиции redux-based приложений отличаются от "классических", унаследованных от jQuery-based приложений.


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


                    В редаксе точкой декомпозиции являются именно sub-state + actions + middleware. Это делается довольно неудобно, и ни в какое сравнение не идет, конечно, с "классическими" компонентами, особенно с непривычки. В первую очередь это связано с тем, что точка монтирования зашита в коде middleware и mapStateToXXX.


                    В редаксе отдельно переиспользуется логика и отдельно переиспользуется UI (в виде dumb components). Ну и, соответсвенно, контейнеры пишем каждый раз.


                    Но сила редакса в том, что он "развязывает" связь один-к-одному между данными и структурой UI. Он легко позволяет отображать одни и те же данные в нескольких видах, без дублирования кода.


                    UI вообще часто нелогичен с точки зрения иерархии, часто верхние уровни зависят от нижних, например, добавляются пункты меню в зависимости от выделенной строки в гриде. Редакс это позволяет делать относительно легко (послать экшен можно из любого места), на "классических" компонентах это сделать красиво невозможно без введения аналога сообщений.


                    1. staticlab
                      20.02.2017 14:49

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


                      Однако вот я почти не видел примеров переиспользования редьюсеров кроме redux-form. Кажется, что на низком уровне просто переиспользуются statefull react components, а на более высоком все приложения намного более специфичны.


                      Редакс это позволяет делать относительно легко (послать экшен можно из любого места), на "классических" компонентах это сделать красиво невозможно без введения аналога сообщений.

                      Так редаксовские экшены и есть по сути сообщения.


                      1. indestructable
                        20.02.2017 15:56

                        Редьюсеры редко переиспользуются потому, что это обычно часть логики приложения (а не компонента). Поведение именно компонента обычно делается внутренним состоянием этого компонента (и его довольно мало, если разобраться).


                        Но это все-равно отличается от классических компонентов, где смешана логика приложения и логика компонента. Особенно это видно на сложных компонентах типа гридов, которые на реакте и редаксе теряют 80% своей сложности.


                        Я не смотрел и не использовал именно redux-forms, и, честно говоря, не совсем понимаю, какую выгоду они несут и что именно автоматизируют.


                        1. TheShock
                          20.02.2017 18:04

                          Особенно это видно на сложных компонентах типа гридов, которые на реакте и редаксе теряют 80% своей сложности.

                          И набирают два порядка сложности на дублицировании кода для каждого одинакового грида.


                    1. vintage
                      20.02.2017 15:02

                      $my_app $mol_book
                          sub /
                              <= Menu $my_menu
                                  items <= menu_items /
                              <= Grid $my_grid
                                  rows <= grid_rows /
                                  selected_row => grid_row_selected

                      namespace $.$mol { export class $my_app extends $.$my_app {
                      
                          menu_items() {
                              const selected = this.grid_row_selected()
                              if( !selected ) return []
                      
                              return [
                                  this.Menu().Copy() ,
                                  selected.removable() ? this.Menu().Remove() : null ,
                                  this.canEdit( selected ) ? this.Menu().Edit() : null ,
                              ]
                          }
                      
                      } }

                      Тут создаётся приложение с 2 панелями: грид и меню. В грид проталкивается список строк, вытягивается выделенная строка, на её основе формируется список пунктов меню взятых из меню, и проталкивается обратно в меню.


                  1. titov_andrei
                    21.02.2017 17:18

                    В ember.js как-то решили эти противоречия? Да и выбор оставили — хочешь компоненты используй, хочешь контроллеры.


                    1. staticlab
                      21.02.2017 17:21

                      Вы у меня спрашиваете? С Эмбером я не работал, но если вы знаете, как они это обошли — не поделитесь?


  1. http3
    17.02.2017 15:51
    -1

    MVC — это лишь разделение кода на уровни: шаблон (UI) и остальной код.
    Дальше можно не читать.


    1. lair
      17.02.2017 15:57

      Вы с Separated Presentation не перепутали?


  1. kmmbvnr
    21.02.2017 12:26

    Сидят программисты на сайте с jQuery 1.8.3 и обсуждают умер ли MVC.


    1. kmmbvnr
      21.02.2017 12:31

      Я открыл tutu.ru, а там тоже jQuery 1.8.3

      MVC мертв, ага.