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

    — Не понимаю, почему люди так восхищаются этим Карузо? Косноязычен, гугнив, поёт — ничего не разберешь!
    — А вы слышали, как поёт Карузо?
    — Да, мне тут кое-что из его репертуара Рабинович напел по телефону.

    Детектив по материалам IT. Часть первая


    Я осознаю, что писать очередную статью на тему Модель-Вид-Контроллер это глупо и вредно для «кармы». Однако с этим «паттерном» у меня слишком личные отношения – проваленный проект, полгода жизни и тяжелой работы «в корзину».


    Проект мы переписали, уже без MVC, просто руководствуясь принципами – код перестал быть похож на клубок спагетти и сократился наполовину (об этом позже, в обещанной статье про то, как мы применяли «принципы» в своем проекте). Но хотелось понять, что же мы сделали не так, в чем была ошибка? И в течении долгого времени изучалось все, что содержало аббревиатуру MVC. До тех пор пока не встретились исходные работы от создателя – Трюгве Реенскауга…


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


    Более 30 лет собранные в MVC идеи и решения остаются наиболее значимыми для разработки пользовательских интерфейсов. Но как ни странно, несмотря на существующую путаницу и обилие противоречивых трактовок, разработчики продолжают довольствоваться информацией «из вторых рук», черпая знания о MVC из википедии, небольших статей в интернете и фреймворков для разработки веб-приложений. Самые «продвинутые» читают Мартина Фаулера. И почему-то почти никто не обращается к первоисточникам. Вот этот пробел и хотелось бы заполнить. И заодно развеять некоторые мифы.



    Мифы: MVC создавался для языка SmallTalk

    Концепция MVC была сформулирована Трюгве Реенскаугом (Trygve Reenskaug) в результате его работы в Xerox PARC в 1978/79 годах. Как правило создание MVC связывают с языком SmallTalk, но это не совсем так. На самом деле Реенскауг работал в группе, занимавшейся разработкой портативного компьютера "для детей всех возрастов" Dynabook под руководством Алана Кэя (Alan Kay).


    Чтобы оценить масштаб и революционность того проекта, нужно иметь ввиду что это были годы, когда для работы с ЭВМ требовалось штудировать многостраничные мануалы и иметь ученую степень. Задача, которую пытался решить Алан Кэй, состояла в том, чтобы сблизить компьютер и рядового пользователя, «сломать» разделяющую их стену. Он хотел обеспечить пользователя средствами, которые были бы предельно простыми и удобными, но при этом давали бы возможность управлять компьютером и сложными приложениями.


    Именно тогда/там закладывались основы графического интерфейса, формировалось понятие "дружелюбного интерфейса". А также разрабатывался язык SmallTalk, вместе с концепциями объектно-ориентированного программирования, чтобы неподготовленный пользователь “мог понимать и писать программы”. Вот как описывает увиденное в Xerox PARC в 1979 году Стив Джобс – How Steve Jobs got the ideas of GUI from XEROX (from 6.30)


    Проект велся около 10 лет, группой очень сильных разработчиков. Найденные в результате решения, подходы, принципы и в области пользовательских интерфейсов, и в области объектно ориентированного программирования и вообще в разработке больших и сложных компьютерных систем были в какой-то степени проссумированы Реенскаугом и составили основу MVC. Так что MVC это действительно прежде всего совокупность направляющих архитектурных идей. В SmallTalk-80 эти идеи всего лишь получили свою первую значимую реализацию. Причем сделано это было уже после ухода Реенскауга из Xerox PARC и без его участия.


    К сожалению в течении долго времени о «реальном MVC» не было практически никакой доступной информации. Первая серьезная публикация от создателей появилась лишь 10 лет спустя – "A Cookbook for Using the Model-View-Controller User Interface Paradigm in Smalltalk-80". Даже Фаулер упоминает, что он изучал MVC по работающей версии SmallTalk – "у меня был доступ к работающей версии Smalltalk-80, чтобы я мог изучить MVC. Я не могу сказать, что это исследование было тщательным, но оно позволило мне понять некоторые аспекты решения, которые другие описания объяснить не смогли".


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


    В результате многие действительно считают MVC схемой или паттерном (из-за чего постоянно возникает вопрос – какая же из множества существующих схем «правильная» и почему их так много?). В более продвинутом варианте MVC называют составным паттерном, то есть комбинацией нескольких паттернов, работающих совместно для реализации сложных приложений (тут обычно упоминаются Observer, Strategy и Composite). И лишь немногие понимают, что MVC это прежде всего набор архитектурных идей/принципов/подходов, которые могут быть реализованы различными способами с использованием различных шаблонов...


    К последним относится в частности Мартин Фаулер. Вот что он пишет: “MVC часто называют паттерном, но я не вижу особой пользы воспринимать его как паттерн, поскольку он включает в себя множество различных идей. Разные люди читают про MVC в различных источниках и извлекают от туда разные идеи, но называют их одинаково — «MVC». Это приводит к большой путанице и кроме того служит источником недоразумений и непониманию MVC, как будто бы люди узнавали про него через «испорченный телефон»…. Я уже потерял счет сколько раз я видел что-то, описываемое как MVC, которое им не оказывалось.”[ GUI Architectures]


    Рискну предположить, что одна из причин «испорченного телефона» заключается в том, что большинство вторичных источников «за кадром» оставляют самое главное – собственно сами архитектурные идеи, заложенные в MVC его создателями, и те задачи, которые они пытались решить. Как раз все то, что позволяет понять суть MVC и избежать огромного количества подводных камней и ошибок. Поэтому в данной статье я хочу рассказать о том, что обычно остается «за кадром» – MVC с точки зрения заложенных в него архитектурных принципов и идей. Хотя схемы тоже будут. Вернее с них и начнем.


    Но сначала ссылки. Исходный доклад Реенскауга – "The original MVC reports". Позже Реенскауг все это более четко сформулировал и оформил в своей последующей работе “The Model-View-Controller (MVC ). Its Past and Present”. Возможно кому-то будет интересна страница, где собраны записи Ренскауга, относящиеся к тому периоду, с его комментариями - MVC XEROX PARC 1978-79.


    Уже упоминавшаяся первая публикация о MVC в языке SmallTalk-80 от разработчиков только в улучшенном качестве "A Description of the Model-View-Controller User Interface Paradigm in the Smalltalk-80 System" (Glenn Krasner и Stephen Pope). Хорошим дополнением служит также статья “Applications Programming in Smalltalk-80.How to use Model-View-Controller” (автор SteveBurbeck учавствовал в разработке компилятора SmallTalk для IBM на основе Smalltalk-80, а также в разработке MacApp). Ну и если кто-то хочет полного погружения – “Smalltalk-80. The Interactive Programming Environment” от знаменитой Адель Голдберг в дискуссиях с которой Реенскаугом и создавались термины Model, View, Controller.


    Схемы MVC


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


    Итак, несмотря на то, что MVC трактуется и изображается очень по разному, во всем этом многообразии все же можно выделить общее «ядро». Общим является то, что везде говорится о неких трех частях — Модели, Виде и Контроллере, которые связаны между собой определенным образом, а именно:


    1. Модель ничего не знает ни о Виде, ни о Контроллере, что делает возможным ее разработку и тестирование как независимого компонента. И это является главным моментом MVC.


    2. Вид отображает Модель. И значит, он каким-то образом должен получать из нее нужные для отображения данные. Наиболее распространены следующие два варианта: 1) Активный Вид, который знает о Модели и сам берет из нее нужные данные. 2) Пассивный Вид, которому данные поставляет Контроллер. В этом случае Вид с Моделью никак не связан.


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


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

    А также он может осуществлять управление Видом/Видами (особенно если их несколько) и соответственно знать о Видах, но это не обязательно.


    Отсюда мы получаем базовые (максимально упрощенные) схемы двух наиболее часто встречающихся разновидностей MVC. Перечеркнутой линией обозначена необязательная связь Контроллера с Видом.


    Model View Controller


    Вот так базовая схема выглядит у Фаулера: "Основные связи между Моделью, Видом и Контроллером. (Я называю их основными, потому что на самом деле Вид и Контроллер могут быть связанными друг с другом непосредственно. Однако, разработчики в основном не используют эту связь.)":


    Model View Controller


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


    Но обычно, под MVC все таки подразумевают вариант с Активной Моделью.


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


    Шаблон Наблюдатель позволяет Модели с одной стороны информировать Вид или Контроллер о том что в ней произошли изменения, а с другой фактически ничего о них «не знать» (кроме того что они реализуют некий заданный интерфейс «подписчика») и тем самым оставаться независимой. Это называется слабым связыванием и считается вторым ключевым моментом MVC.


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


    Таким образом, более продвинутые «схемы MVC» будут выглядеть так:


    Model View Controller


    Замечание: встречаются авторы, которые в термины Пассивная и Активная модель вкладывают совсем иной смысл. А именно то, что обычно принято называть Тонкой моделью (модель содержащая исключительно данные) и Толстой моделью (полноценная модель содержащая всю бизнес логику приложения).


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


    1. Пользователь управляет приложением через Контроллер, а Вид служит исключительно для отображения информации о Модели, и пользователь его лишь видит


      Model View Controller


      Часто указывают/рисуют лишь то, что пользователь действует на Контроллер, а то что он видит Вид опускается.


    2. Пользователь взаимодействует только с Видом. То есть Вид не только отражает Модель, но также принимает команды пользователя и передает их Контроллеру. В этом случае между Видом и Контроллером образуется еще одна связь: прямая (Вид знает о Контроллере и напрямую передает информацию) или, чаще всего, ослабленная (Вид просто рассылает информацию о действиях пользователя всем заинтересованным подписчикам а Контроллер на эту рассылку подписывается)


      Model View Controller



    Замечание: нужно иметь ввиду, что вариант с Пассивным Видом, когда Вид никак не связан с Моделью и данные для отображения ему поставляет Контроллер, иногда называют MVC, а иногда выделяют в отдельную разновидность — MVP и тогда Контроллер переименовывают в Презентер.


    Для иллюстрации всего вышесказанного несколько диаграмм «из интернета» (надеюсь стало понятнее почему они такие разные):


    Model View Controller


    А теперь самое главное — как применяются, что обозначают и чему соответствует Модель Вид и Контроллер при написании приложений?


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


    «Трехуровневый MVC» от веб


    Первый подход идет из веб-программирования, где MVC получил самое широкое распространение, и поэтому в нем максимально отразились свойственные веб-программированию черты. А именно, привязка к трехуровневой архитектуре «клиент–сервер–база данных» и преобладание скриптовых языков. В результате компоненты MVC формально привязываются к трем слоям архитектуры и получается что:


    1. Модель = База Данных
      Модель — это просто данные, которыми оперирует приложение


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


    3. Вид = Клиент (как правило тонкий)
      Вид — это пользовательский интерфейс. Причем интерфейс в этом случае, как правило, понимается в основном исключительно как «дизайн», просто набор графических элементов. Логика же работы этого интерфейса, как и логика работы с данными, выносится в Контроллер

    image alt text


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


    1. Независимость Модели является главным в MVC. Если Модель тонкая, то есть содержит лишь данные, то возможность ее независимой разработки имеет мало смысла. Соответственно при таком подходе теряет смысл и сам MVC


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


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


    4. Поскольку, как правило, тонкой является не только Модель но также и Вид (тупой Вид или тупой интерфейс — Dumb GUI, Dumb View), то, как следствие, в Контроллер помимо всей бизнес-логики приложения помещается также еще и логика управления пользовательским интерфейсом. То есть, вместо разделения бизнес логики и логики представления при таком подходе получается их смешение.

    web MVC


    Программа, конечно, разбивается на множество MVC, соответствующих страницам веб-приложения, и это спасает ситуацию но, увы, не меняет сути. Проблема эта известна, вот неплохая статья — "RIA Architecture".


    Типичные ошибки: смешение в Контроллере бизнесс-логики и GUI-логики

    Хорошая новость заключается в том, что «веб-вариант MVC», всего несколько лет назад бывший самым распространенным, сейчас активно сдает позиции. Плохо то, что он по прежнему распространен, только теперь не в явном, а в замаскированном виде. Поскольку за фразы (цитирую): "Модель это обмен данными с БД и т.п. Контроллер логика обработки этих данных и подготовка к View" сейчас активно «минусуют», то стали писать:


    • Модель — это данные и методы работы с ними
    • Контроллер — обработка действий пользователя и вводимой им информации

    Дело в том, что в объектно-ориентированном приложении нет данных, а есть множество объектов и каждый из них содержит какие-то данные и методы работы с ними. В том числе и объекы доступа к базе данных (если они имеются). Поэтому когда определение Модели начинается со слова «данные», то оно в сущности имеет мало смысла и нередко в завуалированной форме подразумевает все тот же самый доступ к базе данных. В обработку же действий пользователя нередко помещается львиная доля бизнес логики и в результате по прежнему вся, или почти вся, логика приложения часто оказывается в Контроллере.


    «Архитектурный MVC»


    Второй подход гораздо ближе к первоисточникам. Поэтому разберем его подробнее.


    Мартин Фаулер абсолютно прав, когда говорит что MVC это не паттерн, а набор архитектурных принципов и идей, используемых при построении пользовательских информационных систем (как правило сложных).


    Архитектурные принципы мы постарались собрать и описать в статье "Создание архитектуры программы или как проектировать табуретку". Если же говорить предельно кратко, то суть состоит в следующем: сложную систему нужно разбивать на модули. Причем декомпозицию желательно делать иерархически, а модули, на которые разбивается система, должны быть, по возможности, независимы или слабо связаны (Low coupling). Чем слабее связанность, тем легче писать/понимать/расширять/чинить программу. Поэтому одной из основных задач при декомпозиции является минимизация и ослабление связей между компонентами.


    Давайте посмотрим, как эти принципы применяются в MVC для создания первичной архитектуры (декомпозиции) пользовательских приложений. По сути в основе MVC лежат три довольно простые идеи:


    «1» Отделение модели предметной области (бизнес логики) приложения от пользовательского интерфейса


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


    MVC


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


    Задача же взаимодействия с пользователем выносится в отдельный модуль – пользовательский интерфейс и тоже может решаться относительно независимо.


    Именно модель предметной области (Доменная Модель от английского domain model) считается Моделью в «архитектурном MVC» (отсюда и термин). Поэтому так важно чтобы она была независимой и могла независимо разрабатываться и тестироваться.


    "Сердцевиной идеей MVC, как и основной идеей для всех последующих каркасов, является то, что я называю «отделенное представление» (Separated Presentation). Смысл отделенного представления в том, чтобы провести четкую границу между доменными объектами, которые отражают наш реальный мир, и объектами представления, которыми являются GUI-элементы на экране. Доменные объекты должны быть полностью независимы и работать без ссылок на представление, они должны обладать возможностью поддерживать (support) множественные представления, возможно даже одновременно. Этот подход, кстати, так же был одним из важных аспектов Unix-культуры, позволяющий даже сегодня работать во множестве приложений как через командную строку, так и через графический интерфейс (одновременно)." — Фаулер


    «2» Независимость Модели и синхронизация пользовательских интерфейсов за счет шаблона Наблюдатель


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


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


    «3» Разделение Пользовательского Интерфейса на Вид и Контроллер.


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


    MVC


    У меня сложилось впечатление, что суть этого деления мало кто понимает и соответственно может объяснить. Обычно приводят лишь стандартную обтекаемую формулировку, что Контроллер как-то реагирует на действия пользователя, а Вид отображает Модель (поэтому в большинстве реализаций именно Вид подписывается на извещения об изменениях Модели. Хотя, как уже говорилось, подписчиком может быть и Контроллер, либо Вид и Контроллер вместе).


    Поскольку деление пользовательского интерфейса на Вид и Контроллер относится ко второму уровню иерархии, оно гораздо менее значимо чем первичное разделения приложения на доменную модель и интерфейс. Очень часто (особенно когда дело касается простых виджетов) оно вообще не делается и используется «упрощенный MVC», в котором имеется только Модель и единый UI-компонент, представляющий собой объединенный ВидКонтроллер. Более подробно об этом речь пойдет чуть позже.


    «Архитектурный MVC» на первый взгляд выглядит вполне разумно. Но как только мы попытаемся применить его не к учебному примеру из трех классов а к реальной программе, то столкнемся с целым рядом проблем и вопросов, о которых редко пишут, но которые чрезвычайно важны. И касаются они не только пользовательского интерфейса, но и самой Модели. Так что предлагаю таки попробовать с ними разобраться и, наконец-то, "послушать Карузо", то есть обратиться к первоисточникам.


    «Original MVC»: Реенскауг и SmallTalk-80


    Мы привыкли к тому, что MVC почти всегда рассматривается на примере создания какого нибудь простейшего графического компонента, вся «бизнес логика» которого помещается в один класс с данными и парой методов для их изменения. Но что делать, когда речь идет о реальных приложениях, ядро которых состоит из многих взаимосвязанных объектов работающих совместно?


    В общем случае Модель это один объект или множество объектов? И на самом ли деле Модель в «MVC-схеме» тождественна доменной модели, описывающей предметную область и бизнес-логику приложения?


    То, что Модель реализует шаблон Наблюдатель явно указывает на то, что Модель это именно один объект. На это же указывает и то, что Вид и Контроллер должны знать о Модели (для того чтобы брать из нее данные и вносить изменения) и следовательно они должны содержать на нее ссылку. Но тогда, если считать, что под Моделью подразумевается доменная модель, мы вновь приходим к тому что все ядро приложения оказывается в одном объекте. Только теперь вместо толстого уродливого Контроллера, у нас появляется толстая Модель. Толстая Модель конечно лучше, поскольку она независима и в ней, по крайней мере, не смешивается бизнес логика с логикой GUI, но все равно такое решение сложно отнести к хорошей архитектуре.


    Остается второй вариант — Модель это множество доменных объектов, совместно реализующих бизнес логику. Это предположение подтверждает и сам Реенскауг: "A model could be a single object (rather uninteresting), or it could be some structure of objects." Но тогда остается открытым вопрос – кто реализует шаблон Наблюдатель, откуда берет данные Вид, куда передает команды пользователя Контроллер?


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


    Тут можно сказать лишь одно: архитектура, в которой один модуль (Вид или Контроллер), должен «лезть» внутрь другого модуля (доменной модели) и искать там для себя данные или объекты для изменения очень нехорошо «пахнет». Получается что Вид и Контроллер зависят от деталей реализации доменной модели, и если структура этой самой модели изменится, то придется переделывать весь пользовательский интерфейс.


    Для того же, чтобы понять «а как должно быть» предлагаю вновь обратится к «принципам». Когда говорилось о том, что систему надо разбивать на модули, слабо связанные друг с другом, мы не упомянули главное правило, позволяющее добится этой самой слабой связанности. А именно – модули друг для друга должны быть «черными ящиками». Ни при каких условиях один модуль не должен обращаться к объектам другого модуля напрямую и что либо знать о его внутренней структуре. Модули должны взаимодействовать друг с другом лишь на уровне абстрактных интерфейсов (Dependency Inversion Principle). А реализует интерфейс модуля как правило специальный объект — Фасад.


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


    Ну а теперь схема из доклада Трюгве Реенскауга:


    MVC Reenskaug


    Пояснение: Поскольку во времена создания MVC интерфейсы компьютерных программ были в основном текстовыми, то есть, по сути представляли собой простейший вид редактора, то вместо термина «Пользовательский Интерфейс», который появился позже, Трюгве Реенскауг использует термин «Editor» (редактор).


    Таким образом, ключевая идея MVC действительно состоит в том, что пользовательское приложение делится на два модуля – один из которых моделирует предметную область и реализует бизнес логику (доменная модель), а второй отвечает за взаимодействие с пользователем (пользовательский интерфейс). Но при этом Модель в «MVC схеме» вовсе не тождественна доменной модели (которая может быть сколь угодно сложной и состоять из множества объектов), а является всего лишь ее интерфейсом и фасадом.


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


    И если уж рисовать схему MVC, то выглядеть она должна следующим образом:


    MVC


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


    На практике же более адекватной оказывается не сервер-ориентированная архитектура, а клиент-ориентированная. В ней фокус с сервера смещается в сторону клиента и интерфейс, вернее интерфейсы (и фасад или фасады), определяются исходя из потребностей клиентов. Вместо Предоставляемого Интерфейса (Provided Interface) используются Требуемые Интерфейсы (RequiredInterface).


    RequiredInterface


    Конкретные реализации могут варьироваться, но это не суть важно


    RequiredInterface


    Клиент ориентированный подход гораздо лучше соответствует Принципу разделения интерфейсов (Interface Segregation Principle) поскольку в нем вместо единого для всех толстого ProvidedInterface используется множество тонких RequiredInterface.


    Если я не ошибаюсь, именно такой подход используется в архитектуре микросервисов. Там для взаимодействия с множеством сервисов введено понятие шлюза, который является ни чем иным как фасадом — “An API Gateway is a server that is the single entry point into the system. It is similar to the Facade pattern from object-oriented design. The API Gateway encapsulates the internal system architecture and provides an API that is tailored to each client. ” Building Microservices: Using an API Gateway.


    Причем шлюз этот "вместо того чтобы обеспечивать общий единый для всех API, предоставляет различные API для каждого клиента (Rather than provide a one-size-fits-all style API, the API gateway can expose a different API for each client. For example, the Netflix API gateway runs client-specific adapter code that provides each client with an API that’s best suited to it’s requirements)" API Gateway.


    Как мы увидим дальше клиент-ориентированный подход применялся также и в SmallTalk-80. Но вначале давайте просто пере-рисуем схему MVC с учетом вышесказанного:


    MVC


    Смотрим на фасад… Вот он тот самый клей (glue), объект посредник, прокси, фильтр, адаптер… связывающий между собой доменную модель и пользовательский интерфейс и поставляющий нужные данные в нужном/удобном формате.


    Удивительно то, что кроме Реенскауга об этом почти никто не пишет. Хотя некоторые пере-открывают эту идею самостоятельно (пример можно посмотреть тут или тут раздел "Interface-Based Programming Techniques").


    Особенно хорошо тема Моделей-интерфейсов раскрыта в статье одного из JavaGuru — Advanced MVC Patterns. Автор подчеркивает, что Модели это не данные, а исключительно интерфейсы/объекты-посредники/фильтры (Models as Proxies, Models as Filters), обеспечивающие удобный доступ к данным, которые могут находится где угодно – на разных машинах, в разных форматах: “О чем большинство программистов не думает, так это о том, что модели являются всего лишь интерфейсами. Они не должны содержать никаких данных!.. Модели-посредники расширяют охват и позволяют использовать уже существующие данные где бы они не находились”.


    Из-за того что фасад, присутствующий в original MVC, был «утерян», то его роль зачастую берет на себя Контроллер. Отсюда и проистекают представления что Контроллер находится «между Моделью и Видом», служит клеем между ними и обеспечивает нужные Виду данные.


    На форумах нередко встречается вопрос — "Чем контроллер отличается от фасада?". Не смотря на наивность этот вопрос вполне закономерен и на него сложно дать разумный ответ поскольку во многих MVC фреймворках Контроллер на самом деле фактически является фасадом — «Фронт-Контроллер».


    Чем плохо такое решение? Если оно граммотно реализовано, то ничем. Но это в теории. А на практике нередко происходит путаница концепций и понятий и в результате Фронт-Контроллер с одной стороны злоупотребляет своими полномочиями и вместо делегирования команд начинает включать в себя реализацию бизнес логики. А с другой – продолжает одновременно выполнять функции пользовательского интерфейса и в результате в нем происходит уже упоминавшееся смешение «бизнес логики» и «GUI логики» (что собственно и делает его код похожим на огромную свалку).


    Думаю, что пришло время перейти к Smalltalk. Smalltalk-80 создавался очень талантливыми людьми. С документацией в нем действительно имелись проблемы (тем более что «шаблонов проектирования» тогда еще не существовало) но вот с реализацией в основном все было хорошо и пользовательские интерфейсы, конечно же, не взаимодействовали с доменной моделью напрямую.


    Между интерфейсом и доменной моделью (объектами языка SmallTalk) всегда располагался некий промежуточный класс/объект, который обеспечивал удобный интегральный доступ к доменным объектам их данным и методам. Вот эти-то промежуточные объекты (по сути выполняющие роль фасадов) и были в действительности Моделями в SmallTalk-80.


    Например, для работы с кодом в Smalltalk использовались следующие GUI интерфейсы: Inspector, Browser, Workspace,…


    smalltalk-80 MVC


    Вот что пишет об их устройстве Glenn Krasner:


    "Inspector в системе состоит из двух видов. ListView отображает список переменных (слева), а TextView показывает значение выбранной переменной (справа)… Моделью для этих видов служит экземпляр класса «Inspector»… Отдельный класс «Inspector» является посредником или фильтром для того чтобы обеспечивать доступ к любому свойству любого объекта. Использование промежуточных объектов между View и "actual" models является типичным способом изолировать поведение отображения от модели приложения...


    Как и в случае Inspector, промежуточные объекты использовались также в качестве моделей для системных браузеров. Экземпляр класса «Browser» является моделью-посредником для каждого системного браузера..."


    Замечание: название класса-посредника, описывающего промежуточный объект-фасад, обычно совпадало с названием отображающего его виджета. У Inspector промежуточная модель так и называлась «Inspector», а у Browser соответственно – «Browser».


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


    smalltalk-80 MVC


    В конце своей статьи Krasner приводит список использовавшихся в SmallTalk Моделей (наследников базового класса Model): StringHolder, Browser, Inspector, FileModel, Icon… А также отмечает что "the models were almost always some sort of filter class".


    Позже в VisualWorks Smalltalk идея промежуточных Holder-ов была развита и реализована в полной мере. Там для доступа к каждой переменной, принадлежащей доменным объектам, используется свой интерфейс и фасад – ValueModel и ValueHolder. И, как не трудно догадаться, именно ValueModel реализует шаблон Наблюдатель, извещая GUI о происходящих «в домене» изменениях.


    smalltalk Value-Model MVC


    Типичные ошибки: обращение к доменным объектам напрямую

    Поскольку на практике в любом сколько нибудь серьезном приложении сложно обойтись без фасадов, то не удивительно что во многих фреймворках и "модификациях MVC" аналоги фасада или объекта-посредника между GUI и доменной моделью пере-изобретаются под самыми разными именами. Помимо Front-Controller здесь можно упомянуть также ApplicationModel, ViewModel (подробнее см. дискуссию Model-ModelView-Controller) и Proxy-model.


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


    Например, ValueHolder это, как правило, всего лишь обертка вокруг уже существующей доменной переменной, он не должен содержать данные, он содержит ссылку на данные. Вот что пишут: "ValueModel does not need to actually store the value because it is already being stored by another model" (Understanding and Using ValueModels).


    А вот цитата из статьи Advanced MVC Patterns: "Одна из самых распространенных ошибок, которую совершают люди когда используют Swing компоненты, заключается в копировании данных в модели этих Swing компонент. Правильный же способ состоит в том чтобы использовать уже существующие данные, адаптируя их при помощи фильтра… Запомните: никогда не копируйте данные которые можно просто интерпретировать!".


    Рассмотрим следующий простой пример. Если последовать интернет советам и для "добавления элементов в список" использовать код подобный этому (взято со StackOverflow и Adding and Removing an Item in a JList), то будет происходить как раз то самое копирование данных в модель списка:


    Object[] items; // Доменный объект
    
    DefaultListModel model = new DefaultListModel();
    JList list = new JList(model);
    for (int i = 0; i < items.length; i++){
         // КОПИРОВАНИЕ доменных данных в модель списка!
         model.addElement(items[i]);  
    }

    Правильнее, конечно же, использовать данные массива просто обернув их в интерфейс ListModel (тем более что для этих целей создана уже почти готовая AbstractListModel):


    // создаем фасад-адаптер к доменным данным,
    // который просто интерпретирует их нужным образом
    ListModel model = new AbstractListModel() {
        public int getSize() {return items.length;}
        public Object getElementAt(int index) {return  items[index];}
    };
    // передаем созданный фасад списку в качестве модели
    JList list = new JList(model);

    И если надо объединить данные, отфильтровать или преобразовать каким-нибудь образом, то совершенно не нужны промежуточные массивы. Все делается непосредственно в модели-фасаде


    Object[] items1;  Object[] items2; // Доменные объекты
    
    // модель-фасад которая объединяет массивы
    ListModel model = new AbstractListModel() {
        public int getSize() { return items1.length + items2.length;}
        public Object getElementAt(int index) {
            return index<items1.length ? items1[index] : items2[index-items1.length];
        }
    };
    JList list = new JList(model);

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


    Ну а если хочется краткости, то тогда уж лучше так:


    JList list = new JList(items);

    В этом случае Джава сама сделает обертку-адаптер вместо копирования.


    Типичные ошибки: копирование доменных данных в модели GUI-компонент

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


    Мифы: Модель в «MVC схеме» тождественна доменной модели и данным

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


    Но в контексте шаблонов и схем Модель это прежде всего интерфейс и реализующий его объект-посредник (фасад, адаптер, прокси) обеспечивающие удобный и безопасный доступ к доменным данным, которые могут находится где угодно. Реенскауг так и писал: "model object with a façade that reflects the user’s mental model".


    Когда MVC преподносится исключительно как «схема», то наличие «промежуточных моделей» кажется сложным и запутанным. Появляются вопросы ("Чем эти модели отличаются друг от друга?", “Как их правильно использовать?”), неоднозначные трактовки и множество возможностей сделать ошибку.


    Но если понимать заложенные в MVC архитектурные идеи, то все становится предельно ясным: пользовательский интерфейс не имеет права обращаться к объектам доменной модели напрямую. А значит между доменной моделью и пользовательским интерфейсом должнен находиться фасад/посредник/адаптер..., и взаимодействовать пользовательский интерфейс (Вид и Контроллер) может только с ним. Возможностей сделать ошибку – ноль.


    И по большому счету становится все равно каким термином этот объект-посредник называется и какая именно Model-View-Whatever разновидность MVC используется… Начинаешь видеть: какая задача решается, с помощью каких шаблонов и то, насколько хорошо или плохо это делается


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

    Метки:
    Поделиться публикацией
    Реклама помогает поддерживать и развивать наши сервисы

    Подробнее
    Реклама
    Комментарии 387
    • +2
      Я когда-то для своих целей разработки, безотносительно пользовательских интерфейсов — изобрёл для себя модель, которую потом стал называть условно «MVC», хотя это, скорее, «MVDC» — модель-вид-данные-контроллер.
      В ней «Модель» — это данные в ОЗУ, объект, скорее всего составной, возможно содержащий в себе множество объектов (список, коллекцию).
      «Вид» — умеет отображать на экране «Модель», берёт некое «стандартное представление» и отрисовывает его на экране.
      «Данные» — занимаются вводом/выводом из/в файлов, умеет преобразовывать файл в «стандартное представление модели» и наоборот,
      При этом общение все трёх компонентов идёт через интерфейсы, которые, собственно, и оказываются наиболее «неподвижной» частью приложения.
      При этом все три указанные части являются пассивными — а единственной активной частью программы становится Контроллер.
      Контроллер сам не имеет внутренней памяти, не имеет состояний, за исключением «системных» — например, если приложение может работать в нескольких режимах — и занимается только вызывает соотв. методы интерфейсов прочих компонентов.
      • +2

        В силу того, что сказано в посте, надо бы вам определения M и D поменять местами :)

        • 0
          Я бы сказал, что у меня было MCVD. ))
          (Т.е. программы я привык выстраивать вокруг данных в памяти + контроллер, пристраивая остальное «вокруг» этой сладкой парочки. вплоть до того, что контроллер мог сливаться с моделью — в ООП это будет означать, что «Модель» — это поля корневого объекта данных, а «Контроллер» — это его методы. ))
      • +3
        Жду вторую часть
        • +2
          впечатление от статьи: «хорошо, что я познакомился с MVC по Qt»
          • +1
            Спасибо, помогли прояснить некоторые моменты. Например, стало понятно, что контроллер вообще не нужен если используются продвинутые умные элементы управления в представлении, которые сами по себе могут реагировать на уведомления и посылать стандартные команды в модель (например как в WPF/UWP с использованием MVVM).
            • +8
              ) именно по этому в MVVM и нет буковки C. © Кэп
            • +2
              В ходе размышлений о MVC, я пришёл к выводу, что, то MVC что в вебе, можно выделить в отдельную ветвь как минимум по способу работы с событиями. Если в графических приложениях у нас происходит множество событий, и на них должны реагировать множество представлений, то в серверном MVC есть одно событие — http запрос. Второго события, на которое могут реагировать представления просто нет. т.к. как такового объекта представления, который живёт в течение нескольких событий не существует.
              • 0
                А как же всевозможные SPA и просто страницы с большим количеством динамического контента, где различные запросы отправляются на сервер по AJAX и потом меняют отдельные элементы страницы (представления)?
                • 0
                  Сервер-то тут при чем? В случае HTTP он просто отвечает на запросы.
                  • 0
                    Я невнимательно прочитал комментарий.

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

                  • 0

                    С точки зрения серверной части, AJAX — это такой же http-запрос.

                  • +3
                    в серверном MVC есть одно событие — http запрос


                    А потом мы делаем вебсокеты…
                    • 0
                      А потом мы делаем вебсокеты…

                      а пользователь открывает это в IE 6 )))
                      • 0
                        В мире, где существует IE 6, вполне себе существуют и вебсокеты.
                        • 0
                          Веб-сокеты это не HTML5 разве? С миром вэба редко пересекаюсь, мог что-то упустить.
                          • 0
                            Веб-сокет — это протокол передачи данных поверх TCP. Он не имеет никакого отношения к HTML5.
                            • 0

                              Веб-сокет — это еще и API, которое должен поддерживать браузер. IE поддерживает веб-сокеты только с 11й версии.

                              • 0
                                Ну значит меня обманул тов. Мэтью Мак-Дональд в книге «HTML5 недостающее руководство» от 2014 года, в которой он написал, что Веб-сокеты появились в HTML5, но
                                … она (технология веб-сокетов, прим. моё) ещё надохится в процессе развития и не имеет хорошего уровня браузерной поддержки. Изначально технология была добавлена в браузеры Firefox 4 и Opera 11, но была удалена через несколько месяцев в связи с проблемой потенциальных нарушений безопасности.
                                ©
                                • 0
                                  Что там курит товарищ Мак-Дональд? WebSocket — это протокол передачи данных поверх TCP, как и HTTP. HTML (5) — это язык разметки, т.е. всего лишь специальным образом структурированный текст, который может передаваться с помощью любого протокола. Браузер — лишь один из возможных участников обмена данными по этому протоколу. А http://learn.javascript.ru/websockets — всего лишь один из возможных API для использования WebSocket и мне совершенно непонятно, какое отношение он имеет к HTML.

                                  Это ж какую кашу в голове надо иметь, чтобы написать в книжке, что Веб-сокеты появились в HTML5. Он бы еще сказал, что они появились в JSON.
                                  • 0

                                    Ну и как вы будете подключаться к веб-сокету из шестого IE?

                                    • 0
                                      В огороде бузина, а в Киеве дядька. Может, я вообще не поддерживаю IE 6: здоровье дороже, чем полпроцента юзеров. А может, я использую какую-нибудь либу, которая эмулирует веб-сокет для IE 6. Впрочем, какое отношение это имеет к тому, что WebSocket — протокол передачи данных, а HTML — язык разметки?
                                      • 0

                                        Раз вы пытаетесь цепляться к словам — вот вам:


                                        Стандарт HTML5:
                                        4.11 Scripting
                                        6 Web application APIs


                                        Конкретно про веб-сокеты — HTML Living Standard:
                                        9.3 Web sockets

                                      • +1
                                        WebSocket не только протокол передачи данных, но и название JavaScript API, входящего в семейство HTML5 API. Да, HTML тоже не только язык разметки. Даже стандарт HTML 4 специфицировал отображение сущностей языка HTML на DOM API.
                                    • 0
                                      всего лишь один из возможных API для использования WebSocket и мне совершенно непонятно, какое отношение он имеет к HTML.

                                      https://developer.mozilla.org/en/docs/Web/Guide/HTML/HTML5
                                      • 0
                                        что Веб-сокеты появились в HTML5

                                        Есть такая штука как HTML5 API. Это просто группа стандартов. Стандарт самого HTML включен в него же. Как и API для работы с DOM например.

                                        • 0
                                          Ок, каюсь, был сбит с толку названием.
                                    • –2

                                      Я бы и про "поверх tcp" поспорил, т.к. ничего не мешает вебсокетам работать поверх udp или unix socket, т.е. "Веб-сокет — это протокол передачи данных."

                                      • +1

                                        Реализацию веб-сокетов поверх UDP не подскажите?

                              • +1
                                Да, но пропаганда «пишем сайт на php используя MVC» не затрагивает тему вебсокетов.
                                • 0
                                  Но в целом никак ей не противоречит. У нас «сайт» (приложение) на PHP c MVC и веб-сокетами. Просто ещё один тип событий веб-сокеты. На самом деле четвёртый: первый — http-запрос, второй — cli-команда, третий — amqp событие (пуллинг по хрону), а потом и веб-сокеты прикрутили, причём в двух вариантах — через прослойку на node.js и нативно. В ближайших планах честный пушинг amqp. Приложению как таковому (инфраструктуре и бизнес-логике) абсолютно всё равно откуда пришло событие «пользователь такой-то прислал данные о новом(ых) платеже(ах)», оно абстрагируется от канала поступления на самой ранней стадии обработки и дальше идёт по единому маршруту.
                                • 0

                                  давайте подумаем что это меняет.


                                  1. простая модель — запрос/ответ.

                                  Ну то есть мы посылаем на сервер какой-то ивент и получаем ответ. Собственно все. Просто другой транспорт но модель выполнения абсолютно такая же как и в случае с http.


                                  1. Подписка на изменения данных.

                                  Вот тут уже интереснее. Мы получаем какое-то событие о том что мы хотим подписаться на изменения, ну например баланса. Сервер при операциях с балансом будет кидать ивент о том что "воу у нас стэйт поменялся" а какой-то объект будет отслеживать эти события и формировать представление для клиента. Тут уже похоже на MVC c вью которое постоянно обновляет представление стэйта модели.


                                  Но опять же, это вопрос не транспорта а того что нам нужно сделать.

                                • 0

                                  Поэтой причине на бэкэнде хорошо себя показывает такой вариант как Model-View-Adapter. То есть есть некий адаптер между HTTP и приложением, который занимается обработкой "событи" и конвертирует их в какое-то действие в приложении. Так же результат работы приложения конвертируется в HTTP ответ. Ну и т.д.

                                  • +1
                                    Не расскажете поподробней о Model-View-Adapter?
                                    • 0

                                      https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93adapter


                                      То есть идея такая. У вас есть View и есть Model. И они друг о друге ничего не знают. То есть одно и то же View может работать с разными моделями просто за счет смены адаптеров. Ну и наоборот. Одна и та же модель может иметь несколько видов представлений в зависимости от адаптера между ними.


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

                                      • 0
                                        Мне немного напоминает MVP, или ошибаюсь?
                                        • 0
                                          Практический смысл это может иметь в случае, если объекты (скорее модели чем адаптеры) реализуют один интерфейс. И тогда у нас вью уже кое что знает о модели или адаптере. И тогда возникает вопрос — какая разница, где гвозди прибивать?
                                          • 0
                                            Практический смысл это может иметь в случае, если объекты (скорее модели чем адаптеры) реализуют один интерфейс.

                                            Можете пояснить? Ибо у них могут быть разные интерфейсы. Просто между каждой парой view — model будет свой адаптер или цепочка адаптеров.

                                  • 0
                                    Перечеркнутой линией обозначена необязательная связь Контроллера с Видом.

                                    Это как?
                                    Может V и M?
                                    • 0

                                      Вы картинку-то смотрели? Вариант "без связи между V и M" — он на отдельной схеме расположен. Слева же связь между V и M есть, а между контроллером и видом — опциональна.

                                      • 0
                                        Так я и смотрел. Поэтому и спросил. :)

                                        В вебе контроллер практически всегда вызывает рендеринг вида явно (я не говорю, что это правильно). :)
                                        А вот вид практически никогда не лезет в модель сам.
                                        • 0

                                          MVC — это не только веб.

                                          • 0
                                            Вид очень часто лезет в модель. Передает контроллер виду объект $user, а вид лезет в него запросами типа $user->getName()
                                            • 0
                                              необязательная связь Контроллера с Видом

                                              Передает контроллер виду
                                              • 0
                                                Необязательная в теории не значит не существующая на практике.
                                                • 0
                                                  на практике пытаться фанатично трактовать MVC чревато, вы и сами думаю знаете.
                                        • 0
                                          Простите, не очень понятен вопрос. Там прямо под картинкой цитата Фаулера «на самом деле Вид и Контроллер могут быть связанными друг с другом непосредственно. Однако, разработчики в основном не используют эту связь»

                                          А если интерисует «физический смысл», то это когда во время работы приложения одни виды сменяют другие (открываются, закрываются) и считается что всем этим ансамблем управляет контроллер
                                          • 0
                                            Простите, не очень понятен вопрос. Там прямо под картинкой цитата Фаулера «на самом деле Вид и Контроллер могут быть связанными друг с другом непосредственно. Однако, разработчики в основном не используют эту связь»

                                            А если интерисует «физический смысл», то это когда во время работы приложения одни виды сменяют другие (открываются, закрываются) и считается что всем этим ансамблем управляет контроллер
                                          • –8
                                            Но обычно, под MVC все таки подразумевают вариант с Активной Моделью.

                                            Хм, а в вебе обычно пассивные модели. :) Страничка отдалась и все. Ничего в ней больше не меняется. :)

                                            Независимость Модели является главным в MVC.

                                            Независимость приветствуется везде… :)

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

                                            Почему же?
                                            Есть API — используйте его.
                                            Хотите, поместите некоторую логику в модель — и так само используйте API.
                                            Зависимости от M нету, так как M — пустая.
                                            Как вообще может быть зависимость от V?

                                            Отсюда и появился термин ТТУК — толстый тупой уродливый контроллер

                                            Другой вариант — толстая тупая уродливая модель. :)

                                            в Контроллер помимо всей бизнес-логики приложения помещается также еще и логика управления пользовательским интерфейсом

                                            Что это вообще такое? :)

                                            Дело в том, что в объектно-ориентированном приложении нет данных, а есть множество объектов и каждый из них содержит какие-то данные и методы работы с ними.

                                            Прекращайте дрочить на ООП.
                                            MVC возможно не только на ООП головного мозга.

                                            Данных нету. Вокруг сферические объекты. Буквы — это тоже объекты.

                                            Второй подход гораздо ближе к первоисточникам.

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

                                            Мартин Фаулер абсолютно прав, когда говорит что MVC это не паттерн

                                            Та это вам все адекватные люди говорят. Но вы же кастрюли на голову оденете и как носороги упираетесь.

                                            «1» Отделение модели предметной области (бизнес логики) приложения от пользовательского интерфейса

                                            В называемом вами классическом это тоже есть.

                                            «2» Независимость Модели и синхронизация пользовательских интерфейсов за счет шаблона Наблюдатель

                                            К вебу имеет слабое отношение…

                                            Очень часто (особенно когда дело касается простых виджетов) оно вообще не делается и используется «упрощенный MVC»

                                            И выходит черти что. Каша из php и html.

                                            То, что Модель реализует шаблон Наблюдатель явно указывает на то, что Модель это именно один объект.

                                            В один класс пихать методы для работы с БД и бизнес-логику? Перемога.

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

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


                                            Хм.
                                            Предположим, что у нас нет фасада.
                                            Глупо же было из-за изменения движка базы менять шаблоны? :)

                                            Причем шлюз этот «вместо того чтобы обеспечивать общий единый для всех API, предоставляет различные API для каждого клиента


                                            Это же так классно поддерживать несколько API :)

                                            Автор подчеркивает, что Модели это не данные, а исключительно интерфейсы/объекты-посредники/фильтры

                                            Вообще-то да.

                                            обеспечивающие удобный доступ к данным, которые могут находится где угодно – на разных машинах, в разных форматах

                                            Программисты на фреймворках понимают это так, что модели остаются ходилками в БД, поверх которых навешали мусора. :)

                                            Типичные ошибки: копирование доменных данных в модели GUI-компонент

                                            Хм.
                                            Но если мы имеем дело с объектами, то они передаются по ссылке.
                                            А как же как быть, когда нам нужны данные из 2 моделей?
                                            А нагружать этой логикой V не хочется. Проще эти данные объединить в С.

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

                                            +100500
                                            Но пропагандисты фреймворков ведут людей по быстрому пути :)

                                            Поэтому, если есть те, кому интересно и «не надоело», то пишите и я выложу вторую часть полностью посвященную именно этой теме.


                                            Конечно же, выкладывайте.

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

                                            А вторая часть — грамотная.

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

                                            Дополню:
                                            Если логика примитивная и нужна только одному контроллеру, то ее все же можно оставить и в контроллере.
                                            Но не в виде ни под каким предлогом.
                                            • +1
                                              Программисты на фреймворках понимают это так, что модели остаются ходилками в БД, поверх которых навешали мусора. :)

                                              Бред. Мои модели ничего о БД вообще не знают. Ходилка в БД работает поверх них.
                                              Но пропагандисты фреймворков ведут людей по быстрому пути :)

                                              К фреймворкам это не имеет никакого отношения. Можно с фреймворком преобразовывать доменный объект в какой-то DTO или прятать его прокси/адаптером/фасадом, а можно без него не преобразовывать и вообще из шаблона в базу писать.
                                              Но не в виде ни под каким предлогом.

                                              А если логика нужна виду? Банальное: список каких-то значений пустой — выдать параграф «нет данніх», не пустой — відать список.
                                              • +1
                                                Бред. Мои модели ничего о БД вообще не знают.

                                                Вы молодец. :)
                                                Если бы все были такими, то и статьи не было бы. :)

                                                К фреймворкам это не имеет никакого отношения.

                                                Самое непосредственное.

                                                Почти вся разработка сейчас или на фреймворках, или на CMS.

                                                А если логика нужна виду? Банальное: список каких-то значений пустой — выдать параграф «нет данніх», не пустой — відать список.

                                                Та пишите.
                                                Получите то, от чего начали:
                                                Мешанина php и html. :)

                                                Но спасибо хоть ответили, а не как некоторые :)
                                                • 0
                                                  Самое непосредственное.

                                                  Почти вся разработка сейчас или на фреймворках, или на CMS.

                                                  Да без разницы на чём она. не зависит от использования фреймворка отдавать во вью или контроллер объект модели или прятать его за прокси/адаптерами/фасадами или, как вариант, давать дто.

                                                  Та пишите.
                                                  Получите то, от чего начали:
                                                  Мешанина php и html. :)

                                                  Есть шаблонизаторы вообще. Так или иначе логика того что и как показывать (например одни сообщения красным, другие зеленым) должна быть в виде, а не в контроллере или модели.
                                                  • +1
                                                    Да без разницы на чём она

                                                    Да, без разницы на чем.
                                                    Только пропагандисты фреймворков предлагают быстрый путь вместо правильного. :)

                                                    Есть шаблонизаторы вообще.

                                                    Ну тогда в шаблонизаторе будете в базу лазить. :)
                                                    Это уже будет не совсем шаблонизатор. :)

                                                    Хотя я не против вызова из шаблона других виджетов / контроллеров / шаблонов.
                                                    Только это только вызов, без логики обработки данных.

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

                                                    Это ж другое.
                                                    Такая логика уместна в шаблоне. :)
                                                    • 0
                                                      Ну так суть MVC в чём — каждой логике своё место, а не что в виде, например, не должно быть никакой логики.
                                                      • 0

                                                        Вы зря обобщаете «пропагандистов фреймворков». И вообще: кто они, єти пропагандисты?

                                                        • +1

                                                          Логика присутствует на всех уровнях. Просто она разная. А вы передёргиваете.

                                                          • –1
                                                            Вы троль?
                                                            • +1
                                                              Полностью согласен.

                                                              К тому же логика должна присутствовать и в наших рассуждениях. Так, например, когда нужны данные из двух моделей, все обращения к другим моделям происходят из основной модели, соответствующей текущему контроллеру. Иначе опять происходит переползание логики предметной области в контроллеры. ИМХО.
                                                              • +1

                                                                И эта "основная модель" будет являться корнем агрегата сущностей или сервисом.

                                                    • 0
                                                      Если логика примитивная и нужна только одному контроллеру, то ее все же можно оставить и в контроллере.
                                                      Но не в виде ни под каким предлогом.

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

                                                    • +3
                                                      Спасибо, виден системный подход. Жду продолжения.

                                                      Типичные ошибки: обращение к доменным объектам напрямую

                                                      Часто использую в виде передачи в вид через контроллер доменных объектов (сущностей и объектов-значений), но не считаю это ошибкой в общем случае, а просто оптимизацией своего труда — в большинстве случаев создание отдельных фасадов будет заключаться в написании кучи геттеров типа FacadeObject::getSomeValue() {return $this->domainObject->getSomeValue();}. Да, оно изолирует доменный объект от вида и контроллера, не допускает даже в теории (без хаков типа рефлексии) изменение доменных объектов, но в большинстве случаев, имхо, эта изоляция не стоит потраченного времени и усложнения кода, если соблюдать дисциплину — не дергать в виде и контроллере методов объектов, изменяющих их состояние и только в контроллере дергать сервисы, изменяющие состояние домена. В каких-то языках, возможно, помог бы её соблюдать модификатор доступа типа friendly, но в PHP его нет, а в JS вообще модификаторов нет толком.

                                                      Ну и фронт-контроллер отвечает у меня за инициализацию приложения (в PHP) и роутинг пользовательских событий в отдельные контроллеры, которые инициализируют доменную модель для реакции на событие UI, дергают сервисы, передают, если нужно часть данных доменной модели в вид для отображения (в PHP, в JS вид слушает события модели) и сохраняют изменения доменной модели. То есть контроллеры обеспечивают не только UI, но и инфраструктуру для доменной модели, в частности обеспечивают персистентность её данных.

                                                      Сама же доменная модель зависит только от объявленных в ней же абстракций, которые контроллеры заполняют конкретными инфраструктурными реализациями. Иногда, конечно, абстракции текут (прежде всего из-за трудоемкости полной абстракции от инфраструктуры хранения данных), но в целом считаю, что у меня удачный компромисс между стремлением всё сделать по науке и практическими требованиям заказчика прежде всего к скорости разработки. Главное, соблюдать дисциплину и внимательно следить когда действительно пора вводить дополнительный слой абстракций и делить существующую на несколько для изоляции и уменьшения связанности.
                                                      • 0
                                                        внимательно следить когда действительно пора вводить дополнительный слой абстракций

                                                        +1
                                                        Тут преждевременная оптимизация не нужна. :)
                                                      • +1
                                                        Если не по теме, игнорируйте.
                                                        Есть приложение, не веб, десктопное, которое общается с базой данных. Вся бизнес-логика вынесена в хранимые процедуры (или функции в терминах Postgre). Насколько я понимаю, это толстая модель данные+бизнес-логика. В приложении нет ни одного прямого select, insert, update, delete. Соответственно на каждое действие есть соответствующая процедура, с правами для каких-то групп пользователей. Вроде бы всё логично.

                                                        Но попытка узнать, как части этого приложения перенести в веб интерфейс (интранет), натыкается на какое-то фундаментальное непонимание меня веб-программистами. Начиная с того, что авторизацию в таком веб-приложении нельзя делать на основе авторизации в базе данных (пустили в БД, пользователь вошёл, не пустили, не вошёл). Заканчивая тем, что у меня «неправильно» организованы данные, функциями никто не пользуется и права так раздавать нельзя. А разделением прав будет заниматься некая прокладка фреймворка, а все пользователи приложения, в БД будут логиниться под одним пользователей (условным web_user). Так как знаний у меня не достаточно, оценить полный спектр технологий/фреймворков и самое главное структуру такого веб интерфейса я не могу.
                                                        Читая статью, мне показалось, что моя идея имеет права на существование. Я не прав?
                                                        • 0
                                                          А как в десктопном приложении аутентифицируются пользователи? Каждому заведена учётка в СУБД и её данные вводят? В вебе так же предлагается? Делать так можно, просто у многих разработчиков на фреймворках/cms нет знаний как это делать, прочитали когда-то в туториале как настроить соединение с базой с пользователем и паролем из конфига и всё.
                                                          • 0
                                                            Да, учётные данные в БД. Пользователи, которые распределены по ролям, так как на каждый чих (действие) есть процедура, то правами управлять просто. В вебе (конечно с учётом того, что это внутренняя сеть, и соединений будет до 1000) хотелось бы так же, чтобы не плодить сущности, и не заниматься раздачей прав с нуля.
                                                            • 0
                                                              Компромисс — пользователи авторизуются в фреймворке его средствами, там же им назначаются роли, а для каждой роли фреймворк ходит под отдельным пользователем БД, условные web_manager, web_accounter, web_admin, web_director, которым в базе назначено по одной роли. Фреймворк выбирает нужную пользователю роль и от её имени стучится в базу. Во многих фреймворках это делается с минимум разработки, в основном только конфиги написать под каждую роль. Минус — стандартными средствами СУБД не сделать бизнес-логирование, надо дописывать в функции параметр «пользователь» и использовать его (если пустой, то пользователя БД).
                                                              • 0

                                                                Зачем 1к конектов к бд, когда есть persistent connections?
                                                                Что делать когда юзеров станет не 1к, а 10к, 100к. Столько одновременных коннектов уже субд не вытянет.
                                                                Авторизачия через бд весьма узкий кейс, который фреймворками не предусмотрен. Кроме того, не дает каких-либо плюсов по сравнению с классической авторизацией через приложение.

                                                                • 0
                                                                  Плюс — управление пользователями и логирование их действий стандартными средствами СУБД. На уровне СУБД исключается ситуация, что какие-то даные увидит, изменит или удалит тот, кто не должен с градацией вплоть до отдельных столбцов.
                                                                  • 0

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

                                                                    • +1
                                                                      Так я как раз и не думаю, о том, кто и что может увидеть или не может, я один раз добавляю пользователя в роль. Всё. Дальше всё по умолчанию нельзя (нет прав на исполнение процедуры). Дальше, самое страшное что может произойти, это пользователь не сможет что-то сделать, или увидеть.
                                                                      Вся логика в приложении это круто. Поменять условия выборки — поменяй код. Поменялись проверки — поменяй код. При этом надо заставить всех пользователей перезапустить приложение. Громоздкие SQL запросы в коде. Зачем? Если сейчас я чуть меняю хранимую процедуру (параметры передаются те же) и у всех всё работает по-новому. Не говоря уже о фантазиях сделать приложение под другую платформу (веб, macOS).
                                                                      • 0

                                                                        Веб-приложения не надо перезапускать. И код обычно меняется проще, чем схема БД.


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

                                                                        • 0
                                                                          Перезапускать не надо, только если в клиентской (браузерной) части нет логики, так?

                                                                          А про неограниченный доступ к БД с рабочих мест — а какая альтернатива в вебе? Если мы говорим про приложение, которое работает только с БД, и только после авторизации. Зачем какой-то дополнительный компонент авторизации, если уже всё есть – можно/нельзя войти проверяет сервер БД.
                                                                          • 0

                                                                            Клиентскую часть перезапускать не надо, если не менялся API.


                                                                            Зачем какой-то дополнительный компонент авторизации, если уже всё есть – можно/нельзя войти проверяет сервер БД.

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


                                                                            2. Потому что веб-сервер может держать больше соединений чем сервер БД.


                                                                            3. Сервер БД не умеет идентифицировать пользователя через WS-Federation или OAuth/OpenID.


                                                                            4. Если доступ пользователя к столбцам в БД настраивается довольно просто — то доступом к строкам управлять вам придется вручную, и никакие фреймворки тут не помогут.


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

                                                                            А про неограниченный доступ к БД с рабочих мест — а какая альтернатива в вебе?

                                                                            Доступ к БД только от веб-сервера, конечно же. Пароль никому не сообщать, порт закрыть файерволом или биндить на loopback.

                                                                            • 0
                                                                              1. «Проще», это вот опять, сложный вопрос. Я до сих пор не понимаю какой комплект технологий (на сервере и клиенте) мне нужен, чтобы просто вытащить в веб-интерфейс справочник из двух полей. Так чтобы легко добавлять/изменять/удалять данные прямо в гриде.

                                                                              2. Мне не актуально, правда.

                                                                              3. Аргумент, но наверное не для внутреннего использования.

                                                                              Я бы с удовольствием обменялся опытом, проектировал бы БД, за еду обучение веб-подходам в очень узкой области)
                                                                              • 0
                                                                                «Проще», это вот опять, сложный вопрос. Я до сих пор не понимаю какой комплект технологий (на сервере и клиенте) мне нужен, чтобы просто вытащить в веб-интерфейс справочник из двух полей. Так чтобы легко добавлять/изменять/удалять данные прямо в гриде.

                                                                                На клиенте: HTML + CSS + jquery или какая-нибудь библиотека для двусторонней привязки данных (KnockoutJs или AngularLight).


                                                                                На сервере: PHP или другой язык, пригодный для веб-программирования (C#, Java, Ruby, Python).


                                                                                Самым сложным тут будет — избежать отправки на сервер справочника целиком (что чревато конфликтами при одновременном редактировании). Если справочник редактируется монопольно — то задача вообще простейшая, иначе надо будет отслеживать какие строки пользователь менял, а какие — нет.


                                                                                Я бы с удовольствием обменялся опытом, проектировал бы БД, за еду обучение веб-подходам в очень узкой области)

                                                                                Да я и "за так" вам про веб-подходы расскажу. Но лучше все-таки это делать на http://ru.stackoverflow.com/, а не в комментариях к случайному посту на хабре.


                                                                                Аргумент, но наверное не для внутреннего использования.

                                                                                Для внутреннего использования неплохо заходит авторизация через Active Directory (которая на самом деле Kerberos, не путать с авторизацией через LDAP!). И она, насколько я знаю, из всех СУБД работает только с MS SQL Server.

                                                                          • 0
                                                                            Хранить пароли не обязательно в открытом виде и вообще хранить не обязательно. Можно хранить зашифрованными (не путать с захешированными), можно передавать с каждым запросом и даже тоже зашифрованным.
                                                                          • +1

                                                                            Ну так и с логикой в коде так же. Один раз назначили пользователю роль и все. С этой стороны разница только в том, что они хранятся в таблицах типа user и role, а не в системных.
                                                                            С коннектом напрямую в БД проблема в том, что подключенный пользователь имеет доступ ко всем средствам SQL, поэтому надо по умолчанию ограничивать права на всё.
                                                                            С доступом через веб-приложение немного попроще — если приложение не предоставляет возможность для отображения таблицы транзакций, то никто их и не прочитает, без всякой проверки прав. А если предоставляет, то можно например id пользователя добавлять в каждый запрос, чтобы он только свои видел.


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

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

                                                                      • +2
                                                                        1к соединений, это потолок в данном случае, в реальности речь про сотни. 10к и 100к не будет. В чём узость авторизации через БД, я не понял. Плюсы выше про раздачу прав один раз. Равно как, и например, удаление пользователя. В одном месте удалил и не думаешь, откуда и как он ещё мог зайти.
                                                                        • 0
                                                                          Я, честно говоря, давно не интересовался вэб-программированием, но «кейс фреймворками не предусмотрен» звучит странно. Почти как «стандартная библиотека моего любимого языка программирования не предусматривает умножения матриц». Неужели в мире вэба свет окончательно сошелся на фреймворках, и на чистом php уже никто не хочет даже просто «пообщаться с БД»?
                                                                          • 0
                                                                            Логично, что фрймворки пишуться так, чтобы покрыть самые частые способы использования. И решить самые частые проблемы. И да, я не знаю ни одного фреймворка, который бы авторизовал юзеров посредством бд. Но это не значит что этого нельзя сделать или это сложно сделать. Просто это нужно крейне редко.

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

                                                                              Symfony c Doctrine позволяют это делать, причём на уровне конфигов.
                                                                              • +1

                                                                                Эм… это как? Ну то есть, там аутентификация на стороне php происходит, с хэшированием пароля через password_hash и т.д. Да и Doctrine тут не причем, просто есть дефолтный entity user provider.

                                                                                • 0
                                                                                  Это без использования механизма аутентификации Симфони. При создании Doctrine подключения к базе данных, брать параметры не из parameters.yml, а из request. Тупо не аутенфицировался — ошибка подключения, запросил процедуру/вью без необходимых (на уровне БД) прав — ошибка исполнения запроса.
                                                                                  • 0

                                                                                    Это из коробки?

                                                                                    • 0
                                                                                      не представляю как. Ведь контейнер билдится один раз на проде и подменить уже ни чего нельзя… Разве что конструировать ентити менеджер самому
                                                                            • +2
                                                                              Неужели в мире вэба свет окончательно сошелся на фреймворках, и на чистом php уже никто не хочет даже просто «пообщаться с БД»?

                                                                              В целом да. Более того, это считается дурным тоном для большинства задач. Уж как минимум, соединение должен настроить фреймворк по конфигам. Справедливости ради, нормальные фреймворки позволяют и соединение устанавливать с динамическими параметрами, но большинство разработчиков на них, наверное, даже не знают как это делать, из голого ПХП знают как, а в воркфлоу фреймворка как заинжектить динамику не знают, привыкли к «магии».
                                                                              • –2
                                                                                Неужели в мире вэба свет окончательно сошелся на фреймворках

                                                                                Не везде, но фреймворки доминируют.
                                                                                Разработчики то ли обленились, то ли отупели, то ли тупыми и были, то ли не хотят брать на себя ответственность. :) Бла-бла-бла.
                                                                                Много свежей крови, которая кроме фреймворков ничего не умеет.
                                                                                Поколение программистов, не умеющих программировать на языке, на котором написан фреймворк :)

                                                                                а в воркфлоу фреймворка как заинжектить динамику не знают, привыкли к «магии»

                                                                                Но фреймворки тоже толком не умеют. :)

                                                                                Ну такое.

                                                                                Давайте, вахтеры, минусуйте. :)
                                                                                • 0
                                                                                  Разработчики то ли обленились, то ли отупели, то ли тупыми и были, то ли не хотят брать на себя ответственность. :)

                                                                                  Обленились, да. Хороший разработчик — ленивый разработчик. Он не будет писать сотни раз один и тот же код в разных проектах. И даже один раз писать и потом копипастить или подключать не будет, если знает, что есть готовое решение. Это только люди с синдром NIH пишут всё сами, начиная чуть ли не с BIOS.
                                                                                  • +1
                                                                                    Хороший разработчик — ленивый разработчик

                                                                                    Согласен.

                                                                                    если знает, что есть готовое решение

                                                                                    Вот только пользоваться фреймворками люди не умеют.
                                                                                    Вы же сами это говорили. :)
                                                                                    Да и MVC унылый на фреймворках, как показала статья и комменты. :)

                                                                                    Это только люди с синдром NIH пишут всё сами, начиная чуть ли не с BIOS.

                                                                                    Есть понятие unix-way.
                                                                                    Фреймворк — это швейцарский нож, которым никто не умеет пользоваться :)

                                                                                    Это разве нормально, что программист на фреймворке языка не знает языка и не умеет программировать? :)

                                                                                    Хотя да, разные программисты нужны. :)
                                                                                    • +1
                                                                                      «Не хочет писать SQL-запросы вручную» не означает «не умеет программировать».
                                                                                      • 0
                                                                                        «Не хочет писать SQL-запросы вручную» не означает «не умеет программировать».

                                                                                        Карл, а где я такое говорил?.. :)
                                                                                        • 0
                                                                                          Вы так хотите, чтобы вас носом ткнули? Примерно вот здесь:
                                                                                          Дело в том, что в объектно-ориентированном приложении нет данных, а есть множество объектов и каждый из них содержит какие-то данные и методы работы с ними.

                                                                                          Прекращайте дрочить на ООП.

                                                                                          Если вы предлагаете не использовать объекты, по которым запросы к базе данных строятся автоматически, значит предлагаете использовать запросы вручную и массивы.
                                                                                          • –2
                                                                                            Это все ваши домыслы.
                                                                                            Вон из профессии.
                                                                                      • +5
                                                                                        Вот только пользоваться фреймворками люди не умеют.

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


                                                                                        Да и MVC унылый на фреймворках, как показала статья и комменты. :)

                                                                                        MVC это buzz-word. В целом например фэйсбук со своим flux подошел очень грамотно. Они просто переименовали вещи и отгородились от общей концепции. Что бы меньше конфликтов вызывало в понимании.


                                                                                        Фреймворк — это швейцарский нож, которым никто не умеет пользоваться :)

                                                                                        Посмотрите на современные фреймворки. Как правило они состоят из набора готовых самодостаточных компонентов. Обычно есть стандартная сборка этих компонентов которая и именуется фреймворком. Но никто не мешает вам брать и использовать другие компоненты.


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


                                                                                        Есть понятие unix-way.

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


                                                                                        Это разве нормально, что программист на фреймворке языка не знает языка и не умеет программировать? :)

                                                                                        Нет, не нормально. Бизнес логика приложения по хорошему не должна быть завязана на язык. Так же есть такая проблема среди разработчиков что если они выбирают один конкретный инструмент, то пытаются потом задачи подгонять под него же. Например ORM. Это хороший инструмент когда нам надо сделать что-то с каким-то небольшим набором данных. Провести бизнес транзакцию. Но многие начинают впадать в крайности и пытаться тем же ORM решать вопросы репортов, сложных выборок и т.д. Это не означает что "ORM не нужны", это означает что люди любят зацикливаться и не особо хотят думать.

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

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

                                                                                          ЦА фреймворков — плохие программисты? :)

                                                                                          Культ карго, эффект Даннинга-Крюгера и т.п.

                                                                                          А, ну это да. Странно только, что он так сильно распространен среди программистов или «программистов» :)

                                                                                          Они просто переименовали вещи и отгородились от общей концепции.

                                                                                          Ерунда какая-то :)

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

                                                                                          1. Только не все умеют эту сборку готовить :)
                                                                                          2. А что должно быть во фреймворке, если выбросить все компоненты?

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

                                                                                          Хм, но общение может быть организовано посредством какой-то шины :)

                                                                                          Очень часто когда люди кричат «фреймворки не нужны»

                                                                                          Правильней «фреймворки не всем нужны» :)

                                                                                          Но многие начинают впадать в крайности

                                                                                          Об этом и речь, что не нужно впадаться в крайности. :)

                                                                                          Что еще скажу: если человек понимает, что он делает, и знает где что лежит, то плевать, что кто-то считает, что он делает неправильно. :)

                                                                                          Хотя в крайности тут тоже впадать не нужно.
                                                                                          Я вот раньше писал плохо отформатированный код :) Но мне он был понятен :) А сейчас самому противно смотреть на такой код. :)
                                                                                          • +2
                                                                                            Выходит парадокс :)
                                                                                            Для того, чтобы нормально пользоваться фреймворком, нужно быть хорошим программистом.
                                                                                            Но хороший программист может обойтись и без фреймворка.
                                                                                            А плохие программисты не могут нормально пользоваться фреймворком.
                                                                                            Но без фреймворка будет еще хуже. :)

                                                                                            Нет парадокса.
                                                                                            Хороший программист может обойтись без фреймворка, но хорошо подходящий под задачу фреймворк (обычно значительно) ускорит её решение (а плохо подходящий он не выберет).
                                                                                            А плохому программисту фреймворк поможет (или, скорее, заставит) создавать не такой уж плохой код, с которым, в частности, хорошему будет проще разобраться или
                                                                                            ЦА.
                                                                                            В общем ЦА фреймворков — программисты вообще.
                                                                                            • +1
                                                                                              Для того, чтобы нормально пользоваться фреймворком, нужно быть хорошим программистом.
                                                                                              Но хороший программист может обойтись и без фреймворка.
                                                                                              А плохие программисты не могут нормально пользоваться фреймворком.
                                                                                              Но без фреймворка будет еще хуже. :)

                                                                                              Никакого парадокса. Есть такая штука — сюхари.


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

                                                                                              Странно только, что он так сильно распространен среди программистов или «программистов» :)

                                                                                              Это общечеловеческий феномен.


                                                                                              1. Только не все умеют эту сборку готовить :)
                                                                                              2. А что должно быть во фреймворке, если выбросить все компоненты?


                                                                                              1. Да, смотрите про "три стадии обучения".
                                                                                              2. Клей, мосты между компонентами, адаптеры, загрузка конфигураций и базовая структура. Это не много кода обычно.

                                                                                              Хм, но общение может быть организовано посредством какой-то шины :)

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


                                                                                              Правильней «фреймворки не всем нужны» :)

                                                                                              Фреймворки нужны всем. Это каркас. Хотите вы или нет но он у вас появится. Другое дело что есть те 0.1% разработчиков чьи задачи требуют создание своего уникального каркаса.


                                                                                              Что еще скажу: если человек понимает, что он делает, и знает где что лежит, то плевать, что кто-то считает, что он делает неправильно. :)

                                                                                              И тут мы приходим к эффекту Даннинга-Крюгера. Как понять что человек на самом деле понимает что делает а не игнорирует советы других? Проблема то в том что программисты частенько самоучки. И частенько они тусуются в кругу таких же вот самоучек. И невежество начинает укрепляться и распространяться. И в итоге люди исповедующие нормальные подходы остаются в меньшинстве. А поскольку они в меньшинстве то все надеятся на мудрость толпы и т.д.


                                                                                              Я вот раньше писал плохо отформатированный код :) Но мне он был понятен :) А сейчас самому противно смотреть на такой код. :)

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

                                                                                              • –2
                                                                                                Никакого парадокса. Есть такая штука — сюхари.

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

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


                                                                                                Вам не кажется, что те, кто начинал на голом языке, имеют больший профессионализм?

                                                                                                если у вас кучу компонентов связывает одна шина, вы получаете систему с высокой связанностью.

                                                                                                А на фреймворках компоненты как взаимодействуют друг с другом? :)
                                                                                                Service Container — это та самая единая шина. :)

                                                                                                У меня единая шина событий.
                                                                                                А компоненты одного пространства имен свободно вызывают зависимости, но их не много.

                                                                                                Фреймворки нужны всем.

                                                                                                Тогда так:
                                                                                                «Мейстримовые фреймворки не всем нужны» :)

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

                                                                                                Так я и говорю, что это не много. :)
                                                                                                Это можно и самому реализовать, как нужно. :)

                                                                                                И в итоге люди исповедующие нормальные подходы остаются в меньшинстве. А поскольку они в меньшинстве то все надеятся на мудрость толпы и т.д.

                                                                                                Но большинство пишет на фреймворках… :)
                                                                                                • +3
                                                                                                  Беда в том, что программист может застрять на первом уровне и иметь культ карго. :)

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


                                                                                                  На предложение подумать своей головой, в ответ агрессия. :)

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


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


                                                                                                  Процитирую:

                                                                                                  Кого?


                                                                                                  Паттерны лишь словарь. Вы говорите кому-то "используй адаптер" и разработчик понимает что ему надо завернуть объект с одним интерфейсом в другой объект, с другим интерфейсом чтобы сделать совместимость (слово адаптер не просто так выбрано). То есть возможно в документации к фреймворку будут использоваться подобные слова, но в целом я не припомню ни одного где подобные вещи диктовались бы. Обычно вы будете натыкаться на предложение "заюзать паттерн" далеко не в начале документации.


                                                                                                  Ну и опять же. Перед тем как учить паттерны стоит разобраться с такими понятиями как связанность, управление зависимостями, инкапсуляция, декомпозиция задачи и т.д. Структурное программирование можно вместо ООП поизучать. Но это поднимает уже вопрос процесса обучения — его нет. Я часто видел когда на вопрос "с чего начать" кидают книжку по паттернам, хотя человек еще не умеет алгоритмы строить.


                                                                                                  Вам не кажется, что те, кто начинал на голом языке, имеют больший профессионализм?

                                                                                                  тут вопрос в том что есть "начинал". Вот к примеру я начинал писать на PHP не потому что мне надо было заказ на фрилансе закрыть, а потому что нужен был простой консольный скриптик который бы сконвертил 3000 документов из одного формата в другой и я не хотел это делать руками. Пришлось разобраться с основами программирования, регулярками и подобным.


                                                                                                  А многие под "начинать" подразумевают "ну я на выходных почитал про php и сейчас взял пару заказов на фрилансе и времени разбираться нат надо просто проблему решить".


                                                                                                  Перед тем как брать фреймворк в руки разработчик уже должен:


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

                                                                                                  Если вы посмотрите на какой-нибудь Ruby-on-rails и какие-нибудь толковые курсы в духе "RoR за 3 месяца", то там еще до знакомства с самим фреймворком вас сначала научат на ruby писать, потом научат тесты писать и только потом фреймворк.


                                                                                                  То есть знать язык надо, но писать свой фреймворк — плохая идея.


                                                                                                  А на фреймворках компоненты как взаимодействуют друг с другом? :)
                                                                                                  Service Container — это та самая единая шина. :)

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


                                                                                                  У меня единая шина событий.

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


                                                                                                  В целом по поводу событий для снижения связанности… Это очень хороший способ снизить связанность между компонентами. Но помимо связанности есть еще такое понятие как "зацепление" (coheasion) и если связанность должна быть низкой, то зацепление должно быть высоким. Что это значит? Это значит что код который относится к одной области ответственности (все что связано с юзерами например) должно лежать рядом и общаться напрямую без всяких там шин.


                                                                                                  «Мейстримовые фреймворки не всем нужны» :)

                                                                                                  Они нужны 99.9% проектов. Да, это не всем, но подовляющему большинству. А вот "не мэйнстрим" фреймворки не нужны никому. По очень простой причине. Если вы берете фреймворк написанный васей пупкиным у которого 10 звезд на гитхабе, то все расходы на поддержку этого фреймворка ложатся на вас. Фреймворки комьюнити которых насчитывает десятки тысяч разработчиков использовать как-то проще. Тупая экономика.


                                                                                                  Это можно и самому реализовать, как нужно. :)

                                                                                                  на готовых компонентах — да. Но только опять же зачем? в чем смысл? берем symfony/framework-standard-edition и он покрывает 90% всех проектов. А вот если мы хотим делать продукт свой например, и нам очень хочется что бы структура проекта отражало то как мы планируем работать с проектом, и мы хотим точно представлять что мы используем — то тут да. компонентики, контейнер зависимостей какой, и все будет хорошо. Вот только для этого на проекте должен быть синьер разработчик который будет следить за всем этим. Джунам — только стандартные сборки.


                                                                                                  Но большинство пишет на фреймворках… :)

                                                                                                  мне больше нравится интерпретация "большинство используют фреймворки". Если для вас "фреймворк" это структура проекта — ну ок. Для меня "фреймворк" это все что составляет инфраструктуру проекта. То есть если у меня нет фреймворка, он у меня будет.

                                                                                                  • 0
                                                                                                    Кого?

                                                                                                    Чувака одного с форума :)

                                                                                                    тут вопрос в том что есть «начинал»

                                                                                                    Я тоже начинал по маленькому.
                                                                                                    Захотел прикрутить динамику к своему статичному сайту. :)

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

                                                                                                    Но они же знают, что они ищут. :)
                                                                                                    Допустим кеш.
                                                                                                    Или кеш на мемкеше наследует базовый кеш.

                                                                                                    еще такое понятие как «зацепление» (coheasion) и если связанность должна быть низкой, то зацепление должно быть высоким.

                                                                                                    Зацепление высокое :)

                                                                                                    Они нужны 99.9% проектов.

                                                                                                    Я обязан упомянуть статью

                                                                                                    то все расходы на поддержку этого фреймворка ложатся на вас

                                                                                                    Какие ж там расходы.
                                                                                                    Там же не так и много кода по сравнению с самим приложением.
                                                                                                    • +1
                                                                                                      Но они же знают, что они ищут. :)

                                                                                                      они явно объявляют свои зависимости. Например в такой штуке кака конструктор. И им без разницы есть там какой-то конструктор или клиентский код сам все разрулит.


                                                                                                      Зацепление высокое :)

                                                                                                      Опять же, когда зацепление высокое но связанность недостаточно низкая то это приводит к вещам вроде god object. Важен баланс. И я не склонен верить высказываниям что у вас все хорошо (только если в скажете что у вас 90+ покрытие юнит тестами кода, и это не 100 тест кейсов, и это настоящие юнит тесты не выходящие за пределы одного процесса).


                                                                                                      Я обязан упомянуть статью

                                                                                                      Я обязан дать ссылку на докладик: Greg Young — Stop over engineering. Там очень хорошо и про написание своих фреймворков, и про ложный нон конформизм, или за попытки обобщить специализированный функционал....


                                                                                                      Там же не так и много кода по сравнению с самим приложением.

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

                                                                                                      • 0
                                                                                                        Хм. :)
                                                                                                        Я тоже не приветствую оверинжиниринг. :)
                                                                                                        • 0

                                                                                                          собирать свой фреймворк даже из готовых компонентов в 99% случаев оверинженеринг. Например у меня специализация — апишки писать. Я взял стандартный симфони, накрутил туда пару своих решений, пару чужих, тупо своя сборка, и просто использую из проекта в проект. Большая часть "клея" — стандартная. Это значит что можно дать этот проект на суппорт и дальнешнее развитие любому разработчику который знаком с symfony. А особенности и отличия прописать в README.


                                                                                                          Делать же сборку под один проект можно только если вы прекрасно понимаете что делаете. А это уже не новички.

                                                                                                • 0
                                                                                                  Другое дело что есть те 0.1% разработчиков чьи задачи требуют создание своего уникального каркаса.

                                                                                                  Искал комменты, где говорится что только фреймворки наше все.
                                                                                                  Нашел этот.

                                                                                                  Ну ок, я тогда в 0,1% :)
                                                                                                  Спасибо.
                                                                                                  • +2
                                                                                                    Ну ок, я тогда в 0,1% :)

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

                                                                                            • 0
                                                                                              Да и MVC унылый на фреймворках, как показала статья и комменты. :)

                                                                                              Нормальный MVC. Используют его многие ненормально. Например, руководствуются туториалами как пользоваться фреймворками
                                                                                              Есть понятие unix-way.
                                                                                              Фреймворк — это швейцарский нож, которым никто не умеет пользоваться :)

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

                                                                                                Плевать.
                                                                                                Когда будут использовать нормально, тогда и поговорим. :)

                                                                                                Прекращайте троллинг.
                                                                                                • 0
                                                                                                  Голый язык используют еще чаще ненормально, а уж про ненормальные самописный фреймворки и говорить не приходится. О чем еще говорить? )
                                                                                                  • 0
                                                                                                    Ну ок, все говно. :) Довольны? :)
                                                                                        • +1

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

                                                                                • –2

                                                                                  Если бы вы писали БД для веба с нуля — то авторизация средствами БД была бы ужасной архитектурной ошибкой, так же как и бизнес-логика в хранимках. Просто из-за скорости разработки.


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


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


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


                                                                                  Если использовать языки программирования, отличные от PHP, то там можно хранить в сессии не пароль к БД, а непосредственно открытое соединение. Да и на PHP так можно делать, если написать свой http-сервер или fastcgi-обработчик. Но это будет уже намного сложнее.




                                                                                  Основное ограничение подобного подхода — принципиальная невозможность нормально передать из БД наружу событие об изменении данных. Это значит, что никаких веб-сокетов в подобном веб-сайте не появится никогда, да и AJAX при таком подходе будет не лучшим решением. С другой стороны, в интранете большего и не надо.

                                                                                  • +1
                                                                                    «Если бы вы писали БД для веба с нуля — то авторизация средствами БД была бы ужасной архитектурной ошибкой, так же как и бизнес-логика в хранимках. Просто из-за скорости разработки.»

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

                                                                                    Т.е. вы хотите сказать, что весь вопрос только в готовности БД?
                                                                                    Или
                                                                                    Просто из-за скорости разработки.

                                                                                    А что, на другие параметры работы приложений, кроме скорости разработки можно забить?

                                                                                    • –1
                                                                                      Т.е. вы хотите сказать, что весь вопрос только в готовности БД?

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

                                                                                      • 0
                                                                                        Веб-приложение с логикой внутри можно сделать быстрее чем БД с той же самой логикой внутри.

                                                                                        Ничего себе у вас обобщения.
                                                                                        Вы когда нибудь работали с банковскими приложениями?
                                                                                        Когда бывает на обдумывание, как рассчитать какое нибудь говно со сложными процентами, которое придумали маркетологи, уходит времени на порядки больше, чем оформление расчета в процедуре?
                                                                                        И данные вы будете вытаскивать себе в приложение, что бы там их покрутить?
                                                                                        А БД при этом подождет с блокировками?
                                                                                        Может быть стоит принять, что для разных задач существуют разные оптимальные подходы?
                                                                                        • –2

                                                                                          Вот именно "говно со сложными процентами" и делается намного проще на нормальных языках программирования, нежели на SQL.

                                                                                          • –1
                                                                                            Т.е. SQL это «не нормальный» язык программирования?
                                                                                            Я же говорю, вопрос религии всплыл.
                                                                                            • +1

                                                                                              SQL — это прежде всего язык написания запросов, а не программирования. Это уже накладывает некоторые ограничения.


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

                                                                                            • 0
                                                                                              Это же так приятно, написать красивый запрос, который быстро работает и не нагружает сервер. В том числе и вычисление сложных процентов. Сначала вы с кайфом проектируете структуру, которая устойчива к перерасчётам, ковыряниям ручками в данных, изменениям сальдо задним числом, и всему такому, а потом вычисление по всем вкладам/ссудам, и так чтобы одним запросом.
                                                                                          • +1
                                                                                            Вот извините, не соглашусь. Может быть если приложение простое это и верно. У меня только хранимых процедур 2к, если представить, что это переехало в код приложения, да ещё и с обёртками, становится страшно. А зачем это делать, если ровно тоже самое можно сделать не вылезая из сервера, не понят