Ответы пользователя по тегу Проектирование программного обеспечения
  • Где осуществлять валидацию пользовательского ввода в архитектуре MVC?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Давайте размышлять что такое валидация и зачем она нам нужна:

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

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

    Различие тут в том, что все это будет вызывать ошибки. То есть мы не сможем вогнать систему в "невалидное состояние" но пользователь не сможет получить список ошибок, которые он совершил вводя какие-то данные. Все что он получит - отдельные ошибки.

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

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

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

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

    Нельзя из букв "M", "V" и "C" составить слово вечность. Именно по этой причине MVC как подход для организации GUI уже лет 20 как не используется в чистом виде.
    Ответ написан
  • Как выбирать направление архитектуры ООП приложения?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    и как отдельный класс-синглтон


    Зачем? Зачем сингелтон? Ответте на вопрос когда это нужно?

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


    - Разделение ответственности - важный принцип инженерного дела в принципе.
    - Принципы SOLID - хорошо дают понять как работать с зависимостями и делать декомпозицию системы. Сильно пересекается с инкапсуляцией, полиморфизмом и разделением ответственности.
    - Паттерны GRASP - эдакая смесь принципов и паттернов, описывают нюансы цикла жизни объектов и их взаимодействия друг с другом.
    - Закон Деметры - про инкапсуляцию.
    - CQRS - подход по разделению операций записи и операций чтения. Естественно подход такой не работает если вам надо реализовать атомарную запись и чтение, но это минимальный набор задач.
    - Рефакторинг. Он нужен всегда. Его нужно делать по чуть-чуть когда видно что "уже мешает" или "можно было сделать лучше". Ну то есть это не переписывание всего и вся большими кусками, а маленькие изменения которые с течением времени эволюционно меняют архитектуру проекта. Возможно только если код покрыт тестами, это отдельная жирная тема.

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

    https://en.wikipedia.org/wiki/Category:Programming...
    Ответ написан
  • CommonJS / RequireJS - зачем?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Плюс в каких ситуациях такие инструменты должны быть нужны и вообще зачем нужны все эти dependency injection?


    Инверсия управления. Управление зависимостями, снижение связанности между компонентами системы. Что бы то что должно зависить зависило от чего-то и наоборот.

    Не нужно думать что есть универсальные подходы. Есть разные подходы, каждый из которых имеет свои плюсы и минусы.
    Ответ написан
  • Если ли смысл в ОРМ для моего случая?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Есть ли порог когда использование ОРМ становится неоправданым/оправданым? Где он?


    ORM-ки нужня для одного конкретного типа систем - OLTP (On-line Transaction Processing)

    У меня в приложении есть модуль который работает с бд Solr


    У вас есть документы, в документно ориентированных базах данных нет связей. Потому вам нужен Object Document Manager а не Object Relational Mapper.

    Каждый документ может имеет поле parent в котором сохранен ид-родителя, дальше ид-прародителя, дальше прапрародителя итд.


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

    бд в режиме read-only


    Тогда точно не нужна ORM/ODM.

    Итд. Иногда какая-то дополнительная трансформация.


    Но это же трансформация на уровне формирования результата выборки, так? Если так - то это опять же не та проблема.
    Ответ написан
  • Как добавить метод к классу если переопределить класс нельзя?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    завернуть работу с этими сервисами в еще один сервис который собственно будет выступать фасадом и скрывать всю грязь что вы делаете что бы было удобно.
    Ответ написан
  • Проект со сложной логикой на Symfony – как проектировать? Примеры?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Как их организуете (их тогда будут сотни)?


    Раскидываю по неймспейсам. Скажем все действия относящиеся к юзерам находятся в папке Users.

    Только вы учитывайте что CQRS это прикольно но особо не нужно. К примеру это сразу подразумевает что вы используете UUID вместо автоинкрементов и прочей чуши. Можете сделать хотя бы как Дядя Боб предлагает в своей Clean Architecture. Просто сервис на каждое действие.

    Есть ли смысл выносить каждую доменную модель в модуль/микросервис


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

    Раньше для дополнительных действий мне достаточно было использовать что-то вроде beforeUpdate/afterCreate модели.


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

    Как не превратить кидание/получение событий типа PostBeforeEdit/PostBeforeEditHandler в "callback hell"?


    Просто забудьте об этих ивентах.

    ACL. Где храните указанную логику?


    Есть в симфони security vouters, а дальше все зависит от того что вы делаете.

    Как вы версионируете подобные проекты? А если нужна "N-1" рабочая версия на продакшене?


    git + docker теги в мастере. Ветки нужно плодить только тогда, когда у вас система деплоится кастомерам и нужно поддерживать сразу кучу версий. Называется это gitflow.

    На какие проекты (точнее, на код) можете посоветовать посмотреть для лучшего понимания? Ссылки на репозитории?

    На гитхабе катострофически мало примеров хороших приложений на симфони. Да и не только на симфони - в принципе найти в открытом доступе сложный проект - это нереально. NDA и все такое. Такие системы обычно очень дорогие и закрытые со всех сторон.

    p.s. почитайте книжки:

    - Эрик Эванс - Предметно ориентированное проектирование
    - Крэйг Ларман - Применение UML 2.0

    p.p.s. Все ваши загоны не имеют никакого смысла если вы не будете пользоваться практиками вроде Test-Driven-Development, ну или хотя бы покрывать систему интеграционными тестами. Без этого вы не сможете делать частный мелкий рефакторинг, а без этого ваша система быстро превратится в легаси.
    Ответ написан
  • Как организовать фабрику?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Может ну его? Реально? Попробуйте прочитать этот код кому-нибудь, он же не читается. Понятия не имею почему вы решили назвать репозиторий для продукта CatalogProductRepository. Или зачем вам фабрика. Ну и еще - зачем вы инстанцируете все руками. И что это за true.

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

    Я предлагаю вам вооружиться DependencyInjection. Реализация оного есть в любом уважающем себя фреймворке. И избавьтесь от непонятных и неявных констант.

    Моя "идея" заключалась лишь в использовании декоратора для реализации логики кеширования. Суть идеи простая - что бы добавить кеширование не нужно ничего править ни в логике использующую репозиторий, ни в самом репозитории.
    Ответ написан
  • Высоконагруженные системы, каковы принципы разработки?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    давайте так, есть два вида задач:

    - CPU bound - различные алгоритмы, математика, кодирование/декодирование/шифрование... словом все что нагружает процессор.
    - I/O bound - собственно когда у нас идет множество операций с вводом/выводом, где-то 90% задач связанных с WEB и серверной разработкой.

    Для CPU bound стоит использовать языки вроде Си, Rust, Dlang, Go и т.д. Словом языки которые компилируются в эффективный машинный код.

    Для I/O bound - Go, NodeJS, Erlang, Java.... да в принципе не важно какой язык, главное что бы использовались неблокируемые вызовы и отсутствовали блокировки.

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

    Какие языки лучше использовать для этого? Какие не использовать?

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

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

    И на таких объемах даже если бы мы взял Си, если наш алгоритм имеет сложность O(N^2) то как бы ничего тут особо не поделать. И так и так медленно будет. А вот если мы возьмем какие-либо алгоритмы имеющие сложность O(NLogN) то уже возможно что алгоритм этот можно хоть на php/python/ruby имплементить. Так например у меня этот алгоритм реализован на Java и не самым эффективным образом. Справляется.

    Еще влияет скорость разработки (всякие ruby/python/node в этом плане хороши), стоимость поддержки (Си поддерживать сильно дороже чем Go например, хотя всегда можно написать все настолько плохо что проще выкинуть чем поддерживать), стоимость разработчиков.... Скажем найти дешевых сильных разработчиков на Go или Rust будет весьма проблематично.

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

    Собственно главное правило высоконагруженных систем - нагрузочное тестирование а потом уже оптимизации
    Ответ написан
  • Что почитать об архитектуре приложений и фреймворков на php?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    В целом сразу вас расстрою, то что вы хотите нельзя "разобрать" за пару месяцев. На это уйдет пару тройку лет. И книги которые стоит по этой теме прочитать имеет смысл перечитывать. Ну и практика практика практика.

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

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

    но совершенно не имею представления о правильной архитектуре приложений на php


    "Правильно" не бывает, все зависит от задачи. "Правильная" архитектура является:

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

    Вот и все. Далее уже есть принципы SOLID (читать Роберта Мартина), GRASP (Крэйг Ларман), GoF (лучше тут почитать head first design patterns или даже начать с Мэта Зандстры, у него помимо паттернов еще про процессы мельком рассказано).

    Ну и смысла в этом всем нет если вы еще до конца не осознали что есть инкапсуляция и полиморфизм. Многие могут рассказать что значат эти термины, но на практике эти знания они не могут применить (чаще всего страдает инкапсуляция)

    или написании чего-то своего с нуля на чистом php


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

    идеально было бы вообще подробно расписанное сравнение внутреннего устройства нескольких фреймворков


    Берете Symfony или Zend и вперед. Все остальные фреймворки "проще". То есть скрывают больше от разработчика. После них уже можно брать что угодно.

    p.s. еще прочитайте тут: www.phptherightway.com
    Ответ написан
  • Где найти блок схемы php js приложений?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Нигде не могу найти блок схему.


    А вы себе представляете ее размеры? Даже глупо пытаться ее составлять.

    можете нарисовать простую понятную блок схему?


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

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Это называется двусторонней many-to-one связью, и как правила вам стоит избегать оных если вот без них совсем неудобно. Скажем сотруднику совсем не обязательно знать о том что он принадлежит какой-то компании. А потому от свойства company мы можем легко и просто отказаться, если конечно у нас нет какой-то специфичной логики.

    class Employe {
        constructor(firstName) {
            this.firtsName = firstName;
        }
    }
    
    class Company {
        constructor(name, employes){
            this.name = name;
            this.employes = employes;     
        }
    
        rename(name) {
           this.name = name;
        }
    
        addEmploye(employe) {
             this.eployes.push(employe);
        }
    }
    Ответ написан
  • Правильно ли я использую микросервисную архитектуру?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    по идее ваш api gateway или точка входа просит другой сервис сделать работу, делигирует задачу так сказать. А далее уже - как выходит. Иногда да, рендринг шаблонов происходит отдельным адаптером к микросервису (если у нас несколько интерфейсов), иногда самим микросервисом и т.д. Тут как удобнее собственно.
    Ответ написан
  • Чем отличается onion-architecture от n-layer-architecture?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    n-layered архитектура - это просто архитектура построенное на рандомном количестве слоев. оно определяет базовые принципы разделения ответственности и все такое, но на этом все.

    onion - тут уже идет уточнение, что мол в самом сердце у нас core-domain, сущности, базовые бизнес правила. От него уже идет дальше domain layer, application layer и т.д. То есть сначала мы проектируем core-domain а потом уже все остальное.

    Есть еще гексагональная - это опять же уточнения для n-layered архитектур, что мол каждый слой отделен друг от друга за счет dependency inversion. На границах слоев всегда есть интерфейсы, а у внешнего слоя - реализация. Потому ее называют "архитектура портов и адаптеров".
    Ответ написан
  • В какой БД хранить большие объемы видео?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    там хранили в GridFS а не именно в базе, которая в монге позволяет сделать что-то типа распределенного файлового хранилища. Однако я бы не рекомендовал его использовать так как есть более удобные способы организовать хранение файлов на диске. База данных тут не особо влияет.

    Разработчик настаивает на PostgreSQL. Я почитал форумы, хвалят MongoDB.

    Если у вас нет экспертизы в этом вопросе, доверьтесь разработчику. MongoDB очень хорошо распиарена и не более, PostgreSQL намного более надежная база данных.
    Ответ написан
  • В чем преимущество SOA и когда такую архитектуру нужно юзать?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    В общем, я в проекте новенький, но уже прекрасно вижу насколько сильно такое решение усложняет разработку.


    В чем именно неудобство?

    Вообще проблема с SOA в том, что многие воспринимают этот термин немножко по разному. Кто-то вспоминает IBM ESB, кто-то что-то слышал про микросервисы и SCM...

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

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

    Словом... погуглите на эту тему может для начала. У Мартина Фаулера например есть неплохие лекции на эту тему И да:

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


    Я не знаю откуда вы взяли эту информацию. Все крупные проекты которые я знаю скейлятся именно за счет микросервисов.
    Ответ написан
  • Как лучше построить модуль Транзакции в symfony?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    0) Никаких TransactionBundle. Вы эту логику не сможете реюзать, а значит нет смысла делать бандл. Почитайте symfony best practice. У вас должен быть один AppBundle и все, больше ничего. Вы можете пытаться выносить какие-то части инфраструктуры, которая не привязана к бизнес логике в отдельные бандлы для последующего реюза, но бизнес логику приложения реюзать не выйдет.

    1) почитайте про event sourcing. Этот способ хранения данных идеален для платежных транзакций, собственно в банках и т.д. этот подход и используют десятилетиями, да даже та же база данных хранит лог транзакций.

    2) уберите flush их сервиса и вынесите его в контроллер. flush коммитит транзакцию в базу, и нам надо это делать когда мы завершили работу с оными а не "где-то посередине".

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

    4) call_user_func_array в вашем случае - пример плохого решения.

    5) по умолчанию persist использовать нужно только для тех сущностей, которые мы только что создали (в нашем случае - транзакция), либо тех которые мы явно вынули из unit of work (а у нас нет вызова $em->detach).

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

    7) сервисы менеджеры - отстой. Называйте сервисы нормально.

    8) вместо кучи сервисов можно ввести разные объекты транзакций. Например FundTransaction, IncomTransaction и т.д. У вас же в сервисах почти весь код дублируется. А так можно было бы всю логику с этими операциями сложить прямо в сущности.

    9) НИКАКИХ DIE! даже для дебага.

    public function transactionAction(Request $request)
    {
        $data = $request->request;
        $transactionDTO = new TransactionDTO(
             // вообще я бы тут просто ID пользователя возвращал... но я упорот по изоляции приложения от UI
             $this->get('security.token_storage')->getToken()->getUser(), 
             $data->get('sender_account_type'),
             $data->get('recipient_account_type'),
             $data->get('amount')
        );
        // с исключениями разберется фронт контроллер
        $this->get('app.transaction_processor')->process($transactionDTO);
        // вот теперь сохраняем изменения
        $this->get('doctrine.orm.entity_manager')->flush();
    
        return new Response(null, 201); // создали новую запись в журнале транзакций
    }


    class TransactionProcessor
    {
          private $transactionsRepository;      
    
          public function __construct(TransactionRepository $repository)
          {
               $this->transactionsRepository = $repository;
          }
    
          public function process(TransactionDTO $dto)
          {
                // create это статический метод фабрика у абстрактного класса Transaction
                // читать шаблон проектирования "абстрактная фабрика".
                $transaction = Transaction::create($dto->getSender(), $dto->getRecipient(), $dto->getAmount());
                
                $this->transactionsRepository->add($transaction);
          }
    }


    дальше мне по логике не понятно, почему у вас одна транзакция на двух человек, полюбому у sender-а будет один тип транзакции а у ресивера другой. Можно запомнить кому мы чего передавали и только.
    Ответ написан
  • Как верно организовать сервисную архитектуру Symfony2 для поддержки нескольких версий API одновременно?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Вопрос остается только в том, как в PHP , а в частности, в Symfony организовать такую структуру ?


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

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

    Если говорить о архитектуре - идеальный вариант это гексагональная архитектура. Тогда мы будем воспринимать разные версии API просто как разные адаптеры к слою приложения.
    Ответ написан
  • Адекватно ли выглядит моя архитектура?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    все что вы описали решается обычными старыми добрыми модулями (AMD, ES6). По сути смысл есть только в роутере который разруливает какой компонент вам надо отображать на странице в данный момент. И все, далее просто ресолвим зависимости. Но чу, таких решений уже много.

    В целом в этом всем относительно немного смысла если мы конечно не будем сервить все это дело через http2/spdy либо бандлить поумному.
    Ответ написан
  • Стоит ли мешать Golang с Js?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    а зачем? uglify + gzip + настроенное кеширование и оверхэд для пользователя от использования трансляторов/полифилов будет не так заметен (посмотрите статистику, сколько у вас пользователей этих "необычных" браузеров?).

    А вот поддерживать все это выйдет на порядки дороже.

    я вообще когда то думал сделать аналог node.js без их чокнутой виртуальной машины

    и что? Дошли до мысли "это невозможно"? Без полной информации о типах (она может быть получена только в рантайме) вам так или иначе придется писать свою чекнутую виртуальную машину.
    Ответ написан
  • А как Вы избавляетесь от дублирования при решении типичных задач?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Решение: написать базовый модуль Catalog и на его основе сделать модули Films, Games, Stars...


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

    Как вы решаете такие проблемы?

    Устраняем дублирование. Как - зависит от того где это дублирование проявляет себя. Если у нас много однотипных проверок (например в Yii1 был убогий ACL и я не думаю что что-то поменялось для Yii2) с проверкой ролей, можно вынести эти однотипные проверки в какой-то отдельный объект. Symfony и Spring предлагают подход с voter-ми (шаблон chain of responsibility)

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

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

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

    Вариантов как устранить дублирование масса, но суть у всех вариантов одна - берем общее и выносим в общую зависимость.
    Ответ написан