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

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

Насчёт конфигов вставлю сугубо субъективное ИМХО.

Ваш список

database.global.php
development.php
global.php
production.php
services.global.php


читать глазами гораздо сложнее, чем

config.yml
config_dev.yml
config_prod.yml
config_test.yml


Описанная в статье сложность дублирования решается (на примере Symfony) расширением:
В `config.yml` можно указать значения по умолчанию, а в более конкретных `config_*.yml` импортировать глобальный конфиг (`imports: [resource: config.yml]`) и только переопределять его значения.
Выходит более читабельно и компактно, чем то что в статье.

Пример: https://github.com/symfony/symfony-standard/blob/master/app/config/config_dev.yml
Более того, можно пойти дальше и определять еще local_{env}.yml для опций, специфичных в локальной разработке, а также для нестабильных фич (чтобы у коллег не вылетали постоянно ParameterNotFoundException), а также использовать default_parameters.yml.

У Матиаса Нобака в книге описан такой подход:

Параметры в parameters.yml являются необходимыми для функционирования
приложения.

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

В local_{env}.yml вы можете переопределять любые участки конфигурации в
соответствии с вашими текущими девелоперскими потребностями.
Все зависит от целей проекта.

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

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

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

Так или иначе, подход к разработке определит бизнес с его требованиями :)
А разве пакеты фреймворков это не готовые решения?
«Пакеты фреймворков» — это отдельные компоненты? Или имеются в виду сами фреймворки?

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

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

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

Я не совсем понял ваш пример про роутинг, о каком именно «роутинге отдельных модулей» вы говорите? Библиотека роутинга, как правило, это инфраструктурный слой, а конфигурация роутинга в любом случае лежит на плечах программиста.
Слой приложения
— Создаем интерфейс компонента для приложения.
— Создаем реализацию интерфейса в слое приложения. Это может быть как самописный компонент, так и взятый с гитхаба, обернутый под текущий интерфейс приложения.

Доменный слой
— Создаем базовый bootstrap для модулей, в который инжектим необходимые для доменного слоя интерфейсы (Например, интерфесы для добавления правил роутинга, прав доступа, событийный диспатчер)
— Указываем правила роутинга, прав доступа, обработку событий для каждого отдельного модуля, у которого есть что предоставить этим компонентам.

Вот каждый компонент нужно интегрировать, и использование базового интерфейса библиотеки с гитхаба, как правило, не подходит под задачи проекта. Хоть небольшая оберточка (или большая в отдельных случаях), но будет везде.
А чем плох базовый интерфейс библиотек (компонентов, пакетов) сторонних разработчиков? Зачем адаптеры? Обычно адаптеры применяются, когда внутренние интерфейсы слоев уже сформированы, но требует заменить некий компонент аналогичным, но с несовместимым интерфейсом.
В основном три причины:
— Избыточность, протекание абсолютно ненужного функционала на доменный слой. Может навредить, потому что предоставляет все возможности его причинить.
— Недостаток какого-либо функционала, который необходим. Например, добавить в роутере версионирование api.
— Более строгий интерфейс, который предостережет от множества ошибок в будущем.
Я так понимаю, вы говорите о некотором слое абстракции над инфраструктурным, позволяющем более строго структурировать его для доменного слоя?
Я говорю о двух слоях: приложение и домен. Приложение предоставляет домену необходимые зависимости и интерфейсы для своей настройки.

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

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

А что есть в вашем понимании «ядро»? «Слой приложения»?
https://habrahabr.ru/post/267125/
Ну в общем то же самое, о чем я и говорил: «вы говорите о некотором слое абстракции над инфраструктурным».

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

К примеру Zend-Http — имеет не стандартизированный PSR интерфейс, используется напрямую в MVC контроллерах.
Монолит предоставляет или диктует архитектуру постройки приложения. У всех его компонентов и расширений есть интерфейсы для этого. Когда начинаешь отходить от того, что предоставляет фреймворк, рано или поздно приходишь к своему набору библиотек, и сам фреймворк становится не сильно нужен. Разве что отдельные компоненты от него.

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

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


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


  • symfony/dependency-injection
  • symfony/config
  • doctrine/dbal
  • symfony/yaml
  • nikic/fast-route
  • zendframework/zend-diactoros

И это действительно удобно.

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

image
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации