
В предыдущей статье «Как организовать структуру приложения» обсуждались различные подходы к организации кода, включая монолитную архитектуру, многослойную архитектуру и принципы чистой архитектуры. В ней я акцентировал внимание на важности понятной структуры кода, которая облегчает понимание, внедрение новых функций и снижает вероятность ошибок. Особое внимание уделялось критериям понятности, таким как чёткое назначение файлов и папок, разделение логики по модулям или функциональным зонам, использование самодокументируемых названий и соблюдение стандартов кодирования. Также были рассмотрены проблемы, возникающие при неструктурированной организации кода, такие как сложность навигации, отсутствие модульности и нарушение принципов SOLID и GRASP.
В этой статье мы продолжим эту тему, сосредоточившись на сравнении двух подходов к организации кода: Package by Feature и Package by Layer. Мы подробно рассмотрим, как каждый из этих методов влияет на структуру проекта, поддерживаемость и масштабируемость кода.
? Примеры из реальной жизни
Пример №1. Строительство города
Представь, что ты строишь город. В этом городе есть дома, школы, магазины, парки.Ты можешь организовать город по-разному:
Package by Layer – это когда все одинаковые здания стоят в одном месте: Все магазины в одном районе, Все дома в другом, Все школы в третьем. Хотели бы жить в таком городе?
Package by Feature – это когда у тебя есть районы, где всё нужное находится рядом: В одном районе есть и дома, и магазины, и школы – всё для жителей этого района.
Пример №2. Организация одежды в гардеробе
Представь, что ты складываешь одежду в шкафу. Ты можешь разложить ее по-разному:
Package by Layer – все футболки на одной полке, все брюки на другой, а все носки в отдельном ящике.
Package by Feature - А теперь представь, что ты складываешь вещи для разных занятий. Все вещи для плавания - в одном месте (купальник, полотенце, очки), все вещи для школы - в другом (учебники, тетради, ручки).
Пример №3. Организация кухни ресторана
Представь, что у нас есть ресторан и несколько поваров и нам пришел заказ приготовить пиццу, салат и десерт. У тебя есть много ингредиентов и инструментов: мука, сыр, помидоры, огурцы, яйца, миксер, ножи, доски для нарезки и так далее. Тебе нужно организовать всё так, чтобы готовить было удобно.
Package by Layer - Этот способ похож на то, как ты можешь разложить всё по типам, независимо от того, для какого блюда это нужно. Например:
Коробка "Все овощи"
Коробка "Все инструменты"
Коробка "Специи"
Если ты готовишь пиццу, тебе нужно взять коробку с овощами, коробку с инструментами, коробку с сыпучими продуктами и коробку с посудой. Это занимает много времени и сил. Ты можешь запутаться, потому что всё разбросано по разным коробкам.
Package by Feature - ты можешь разложить всё, что нужно для каждого блюда, в отдельные коробки или зоны на кухне. Например:
Коробка "Пицца"
Коробка Салаты
Коробка Дисерты
Ты не путаешься, потому что всё для каждого блюда лежит в одном месте. Повара не мешаю друг другу.
Пример №4. Собираем школьный рюкзак
Представь что нам нужно собрать школьный рюкзак.
Package by Layer - это как сложить все учебники вместе, все тетради вместе, все ручки вместе. Удобно, когда нужно найти все учебники, но неудобно собираться по предметам.
Package by Feature - это как сложить отдельно все для математики (учебник, тетрадь, линейка), отдельно все для рисования (альбом, краски, кисточки). Удобно собираться на конкретный урок, но сложнее найти все учебники сразу.
? Как парадигмы программирования влияют на организацию кода?
Прежде чем углубляться в организацию кода, важно понимать, что разные парадигмы программирования могут влиять на выбор между Package by Layer и Package by Feature.
? Обектно ориентированое програмирования (ООП) и организация кода
ООП — это парадигма, в которой программа строится вокруг объектов, которые представляют собой экземпляры классов. Основные принципы ООП включают:
Инкапсуляция: Сокрытие внутреннего состояния объекта и предоставление доступа к нему только через методы.
Наследование: Возможность создания новых классов на основе существующих, что позволяет повторно использовать код.
Полиморфизм: Возможность объектов разных классов обрабатываться как объекты одного класса.
-
Абстракция: Упрощение сложных систем путем моделирования классов, которые отражают только существенные характеристики.
Package by Feature
Package by Feature естественным образом поддерживает принципы ООП, такие как инкапсуляция и сокрытие реализации. Классы, связанные с одной функциональностью, группируются вместе, что упрощает понимание и поддержку кода.
Позволяет инкапсулировать всю логику, связанную с конкретной функциональностью, внутри одного пакета, что соответствует принципам инкапсуляции и абстракции.
Такой подход способствует созданию высокосвязных модулей с низкой связанностью между ними, что соответствует принципам SOLID.
Легче соблюдать принцип единственной ответственности (SRP), так как каждый пакет отвечает за конкретную функциональность.
Лучше сочетается с DDD (Domain-Driven Design), так как позволяет группировать объекты, связанные с одной бизнес-фичей, в одном месте.
Package by Layer
Package by Layer в ООП часто встречается в классических монолитах, где слои (контроллеры, сервисы, репозитории) разделены, и каждый слой отвечает за свою часть логики.
При package by layer объекты и классы, отвечающие за разные аспекты одной функции, также оказываются разделенными по разным слоям. Это может затруднить применение принципов ООП, таких как полиморфизм, и привести к созданию более сложных и запутанных связей между объектами.
? Функциональное программирование (ФП) и организация кода
ФП — это парадигма, в которой программа рассматривается как набор функций, которые принимают входные данные и возвращают результаты. Основывается на идее чистых функций, неизменяемости данных и композиции. Основные принципы ФП включают:
Чистые функции: Функции, которые не имеют побочных эффектов и возвращают одинаковый результат для одних и тех же входных данных.
Неизменяемость: Данные не изменяются после создания, вместо этого создаются новые данные.
Функции высшего порядка: Функции, которые могут принимать другие функции в качестве аргументов или возвращать их.
Рекурсия: Часто используется вместо циклов для обработки данных.
Функциональное программирование основывается на идее чистых функций, неизменяемости данных и композиции. В ФП акцент делается на том, что делает программа, а не на том, как она это делает. Это ведёт к иному подходу к структуре кода:
Package by Feature
Хорошо сочетается с ФП, так как функциональность группируется вокруг конкретных задач или доменных областей. Это позволяет создавать модули, которые инкапсулируют логику, связанную с определенной функцией.
Функции, которые работают с одними и теми же данными или решают одну задачу, находятся в одном месте, что упрощает композицию функций и их повторное использование.
Такой подход способствует созданию чистых функций, так как каждая функциональность изолирована и не зависит от глобального состояния.
Package by Layer
Противоречит принципам ФП, так как он разделяет код по техническим критериям, а не по функциональности. Это может затруднить композицию функций и привести к разбросу логики по разным слоям. Функциональный код может стать менее читаемым, если функции, связанные с одной задачей, находятся в разных пакетах.
? Что говорят эксперты?
1️⃣ Эрик Эванс в "Domain-Driven Design"?
Эрик Эванс вводит четырехслойную архитектуру (Layered Architecture), которая помогает разделить бизнес-логику, инфраструктуру, пользовательский интерфейс и доступ к данным. Однако он не настаивает на конкретной структуре директорий, а лишь подчеркивает важность разделения зон ответственности.
"При создании сложных программ критически важно разделить код на слои с разными зонами ответственности."
— Эванс, DDD, Глава 4 "Изоляция доменной логики"
? Четыре слоя по Эвансу:
Доменный слой (Domain) должен быть изолирован от инфраструктуры. (Entities, Value Objects, Aggregates)
Сценарии использования (Application) управляют бизнес-процессами, но не содержат бизнес-логики. (Use Cases)
Инфраструктурный слой (Infrastructure) реализует хранилища данных, API, интеграции.
Интерфейсный слой (UserInterface) отвечает за взаимодействие с пользователем
Эванс не говорит, что именно так должна быть организована структура файлов. Он дает концепцию разделения ответственности, но не конкретное правило именования папок. Также Эванс подчеркивает важность Bounded Context и разделения кода по контекстам, а не только по слоям.
"Когда большая система делится на несколько Ограниченных Контекстов (Bounded Contexts), каждый из них имеет свою собственную доменную модель и логику. Код должен быть организован так, чтобы четко отражать эти границы."
Это намекает на Package by Feature, когда код разделен по фичам/контекстам (Bonus/, Customer/, Order/), а не просто слоям (Domain/, Application/, Infrastructure/).
2️⃣ Вон Вернон в "Implementing Domain-Driven Design"
Вон Вернон также поддерживает разделение слоев, но он более гибко подходит к организации кода. В книге "Implementing DDD" он даже упоминает Package by Feature как возможный вариант!
Bounded Context и организацию кода:
Ограниченный контекст (Bounded Context) — это центральный паттерн в Domain-Driven Design (DDD). Он определяет границы, в рамках которых конкретная модель применима и остается согласованной. Организация кода вокруг ограниченных контекстов, а не только вокруг технических слоев, помогает сохранять ясность и соответствие бизнес-домену.
"Ограниченный контекст (Bounded Context) — это логическая граница. Применение архитектурных слоев внутри него — это выбор, а не требование. Главное — сохранить чистоту и выразительность доменной модели в рамках этой границы."
- Вернон, IDDD, Глава 2: Границы контекста
Организация кода и возможные подходы:
«Организация кода строго по слоям часто приводит к искусственному разделению ответственности. Вместо этого рассмотрите возможность группировки кода по доменным концепциям в первую очередь, а затем решите, нужны ли слои внутри каждого контекста.»— Вон Вернон, Реализация Domain
- Вернон, IDDD, Глава 4: Стратегическое проектирование с использованием ограниченных контекстов*
Что это говорит о структуре кода?
"DDD не диктует жесткую структуру пакетов. Важно, чтобы код отражал границы контекста и модель домена."
— Вернон, IDDD, Глава 2 "Границы контекста"
Он признает, что Package by Feature можно использовать внутри DDD и советует группировать код по Bounded Context, а внутри можно использовать слои. Также предлагает гибридный вариант между Package by Layer и Package by Feature:

3️⃣ Карлос Буэносвинос, Кристиан Соронеллас и Кейван Акбари в книге «DDD in PHP»
В книге PHP in DDD также затрагивается вопрос организации кода, включая модели, слои и Bounded Context. Авторы книги ориентируется на принципы Эванса и Вернона, но с адаптацией под PHP.
Поддержка Bounded Context и Package by Feature
"Хорошая архитектура PHP организует код вокруг доменных концепций, а не технических слоев. Каждый контекст должен иметь свою собственную доменную логику, независимую от инфраструктуры."
— PHP в DDD, Глава 6: Организация кода с использованием ограниченных контекстов.
Поддерживает Bounded Context и Package by Feature, а не только слои. Код внутри Domain Layer должен скрывать детали реализации и работать через Use Cases.
Слои используются гибко
"Слоеная архитектура — полезный инструмент, но она не должна диктовать, как структурировать ваше PHP-приложение. Главное — отделить бизнес-логику от инфраструктуры."
— PHP в DDD, Глава 10: Роль уровней приложений и инфраструктуры
4️⃣ Дядюшка Боб в чистом коде
Взгляните на Принципы дизайна упаковки дядюшки Боба. Он объясняет причины и мотивы, лежащие в основе этих принципов, которые я подробно рассмотрел ниже. Следующие три принципа упаковки касаются связности упаковки, они говорят нам, что положить внутрь упаковки:

Как это связано с пакетированием по функциям и пакетированием по слоям?

Принципы дяди Боба показывают, что Package by Feature — более гибкий и масштабируемый подход, так как:
✅ Избегает циклических зависимостей.
✅ Каждая фича меняется независимо.
✅ Группирует код по смыслу, а не по техническим слоям.
Однако, если вы используете Package by Layer, вам нужно очень тщательно управлять зависимостями, чтобы не нарушить принципы! ?
Сравнение подходов к организации кода в DDD

Ключевые моменты:
? Ограниченный контекст как основа (как подчеркивают все три автора).
? Package by Context + Package by Layer внутри каждого контекста.
? Гибкое использование слоев (отделяем домен от инфраструктуры, но избегаем излишней сложности).
? Доменная модель играет ключевую роль (Сущность, Агрегат, Объекты-Значения).
? DDD не диктует структуру папок, но требует четкого разделения ответственности.
? Главный принцип: DDD → сначала контексты, затем слои, а не наоборот! ?
? Use Cases в Чистой архитектуре и Package by Feature
Use Cases — это один из ключевых элементов Чистой архитектуры, который отвечает за обработку бизнес-логики.
Package by Feature — это способ организации кода, при котором все файлы, связанные с одной функциональностью (фичей), хранятся в одной папке.
Эти два подхода отлично дополняют друг друга: Use Cases позволяют выделить бизнес-логику, а Package by Feature делает кодовую базу более модульной и понятной.

Use Cases и Package by Feature не противоречат друг другу. Напротив, они отлично работают вместе, поскольку обе методики направлены на улучшение структуры кода.
Use Cases помогают изолировать бизнес-логику и делают код тестируемым.
Package by Feature позволяет хранить весь код, связанный с одной функцией, в одном месте, делая его модульным.
Комбинируя эти подходы, вы получаете лучшее из обоих миров. В результате достигается:
Гибкий код, сгруппированный по фичам, который можно легко перемещать и тестировать независимо.
Поддерживаемый и масштабируемый код, который проще сопровождать и расширять.
Удобная для разработчиков кодовая база, в которой легче ориентироваться и работать.
Такое сочетание ведет к чистой, модульной и эффективной архитектуре. ?
? Когда что использовать?
В PHP-проектах оба подхода — Package by Feature и Package by Layer — применяются в зависимости от архитектурных решений и масштабов проекта. Давай разберем их с примерами.
Package by Layer подходит, когда:
У вас небольшое приложение
Много новых разработчиков в команде
Нужна простая, понятная структура
Функциональность тесно связана между собой
Package by Feature подходит, когда:
У вас большое приложение
Разные команды работают над разными функциями
Функциональность слабо связана между собой
Важна независимость модулей
Планируете переход на микросервисы
Проект большой с четкими доменными границами
Команда знакома с DDD
Используете собственную архитектуру или модульные фреймворки
? Как организовать код?
Давайте рассмотрим на примерах.
Package by Layer (Пакетизация по структурным слоям)
Этот подход разделяет код по уровням ответственности:
? Controller (контроллеры) – обработка HTTP-запросов
? Service (сервисы) – бизнес-логика
? Repository (репозитории) – работа с БД
? Entity (сущности) – модели данных

Package by Layer (Пакетизация по архитектурным слоям)

Минус этих подходов в том, что логика одной фичи разбросана по разным слоям. При добавлении новой фичи приходится вносить изменения в несколько слоев.
Package by Feature (Пакетизация по фичам)
Здесь код группируется по фичам (сценариям работы), а не по слоям.

DDD и организация кода
На своем опыте я сталкивался с несколькими подходами. Я покажу два из них. Оба подхода технически работоспособны и потдерживают тактические патерны. На практике часто используется гибридный подход, который сочетает лучшие стороны Package by Feature и Package by Layer.
Подход №1. Доменно-ориентированные слои

С точки зрения DDD и Layer Architecture, более предпочтительным является такой подход и вот почему:
Ограниченные контексты (Bounded Contexts)
Первый подход лучше отражает концепцию ограниченных контекстов в DDD
Каждая функциональная область (order, bonus) представляет собой отдельный ограниченный контекст
-
Это обеспечивает лучшую изоляцию бизнес-логики и уменьшает связанность между разными доменами
Модульность и масштабируемость
При первом подходе легче добавлять новые функциональные модули
Каждый модуль содержит все необходимые слои и может развиваться независимо
-
Проще работать нескольким командам над разными модулями
Поддержка и навигация
Легче находить весь связанный код конкретной функциональности
Проще понять границы каждого модуля
-
Меньше риск случайного смешивания кода разных доменов
Соблюдение принципов DDD
Лучше отражает стратегический дизайн DDD
Четче видны границы агрегатов и доменных сервисов
Проще контролировать зависимости между модулями
Подход №2. Слои с доменными компонентами
Этот подход имеет следующие недостатки:

Смешивание разных доменных моделей в одном каталоге
Сложнее контролировать зависимости между доменами
По мере роста проекта становится труднее навигировать по коду
Выше риск нарушения границ между доменами
Советы по организации DDD-проекта:
Начните с выделения ключевых доменов.
Определите границы контекстов.
Создайте базовую структуру папок.
Поместите общий код в отдельный модуль shared/common.
Используйте чистую архитектуру внутри каждого домена.
Определите четкие правила взаимодействия между доменами.
Выводы
Оба подхода к организации кода имеют свои преимущества и недостатки. Выбор между package by feature и package by layer зависит от конкретных требований проекта и предпочтений команды разработчиков.
В целом, package by feature кажется более подходящим для современных приложений, так как он лучше сочетается с принципами ФП и ООП, способствует созданию более модульного и понятного кода, а также облегчает разработку и поддержку приложения. Особенно хорошо этот подход подходит для проектов, использующих DDD.
Однако, важно отметить, что package by layer также может быть эффективным в определенных ситуациях, особенно в проектах с четко выраженной слоистой архитектурой и строгими требованиями к разделению ответственности между слоями.
Вне зависимости от выбранного подхода, важно придерживаться единого стиля кодирования и обеспечивать хорошую документированность кода, чтобы облегчить его понимание и поддержку.
Источники
Комментарии (27)
GospodinKolhoznik
16.02.2025 09:31Package by Layer – это когда все одинаковые здания стоят в одном месте: Все магазины в одном районе, Все дома в другом, Все школы в третьем. Хоели бы жить в таком городе?
Сомнительная аналогия. В городе расстояние до магазина имеет значение. А в ПО разве так? Может быть ссылки на методы или данные из другого модуля вызываются гораздо дольше чем аналогичные ссылки в своем модуле?
dykyi_roman Автор
16.02.2025 09:31Комментарий уходит в сторону производительности, а статья ведь про связность (cohesion) и сцепление (coupling).
Скорость вызова методов или доступа к данным внутри одного модуля vs. из другого модуля – это не относиться к выборе структуры кода. В статье речь идет не о производительности, а о логической связанности (cohesion) и слабом сцеплении (low coupling).
Аналогия с городом помогает представить, насколько неудобно, когда связанный между собой функционал разнесен по разным местам.
В Package by Feature, например весь код связанный с конкретной функциональностью, лежит рядом, что упрощает поддержку и развитие системы. Поэтому аналогия с городом тут не про расстояние, а про удобство организации и поддержку структуры.
GospodinKolhoznik
16.02.2025 09:31Если есть возможность телепортироваться в любой магазин города со скоростью вызова функции в языке программирования, то в чём проблема, что все магазины города собраны в одном месте? Это будет даже красиво.
vadimr
16.02.2025 09:31Прорвёт в этом месте канализацию – и город останется вообще без магазинов. Паразитная зависимость.
В случае программирования – пошли исправлять модуль ради одного, а сломалось при этом другое.
GospodinKolhoznik
16.02.2025 09:31А так дело в канализации! Потому что я думал вы приводите аналогию города с точки зрения шаговой доступности магазинов, школ и т.п.
Что касается модулей. А как поможет не сломаться, если эти два метода будут разнесены по 2 разным модулям? Мне казалось, что модули нужны чтобы ограничивать области видимости функций и данных. Ну и просто чтобы придать коду какую то иерархию для удобства человеческого восприятия. А если 2 сущности А и Б, где Б зависит от А, значит в любом случае для Б доступна видимость А. И если изменить А, есть риск того, что сломается Б и находятся они в одном модуле или в разных нет разницы.
Т.е. я понимаю, что если ремонтировать один магазин, то есть риск, что выключат свет в соседнем магазине тоже, и тогда действительно лучше разнести магазины в разные части города. Но с методами, которые зависят друг от друга так не работает. Либо делаем методы независимыми, и тогда меняя один не сломаешь другой даже если они в одном модуле. Либо они зависимы и вместе ломаются даже если разнесены по разным модулям.
vadimr
16.02.2025 09:31Модуль - это не только область видимости, но и, как правило, единица трансляции и единица редактирования исходного текста программы. И, как следствие, единица дистрибутива тоже.
GospodinKolhoznik
16.02.2025 09:31Замечательная общая фраза. Только она не объясняет как модуль поможет справиться с тем, сломается или не сломается зависимость?
Можете привести пример, где метод B зависит от метода A и в случае когда они в одном модуле B ломается при изменении A, а когда они в разных модулях не ломается?
vadimr
16.02.2025 09:31Если Вася физически не работает с файлом, содержащим функции, необходимые Пете, то он и не помешает Пете.
Ваши ожидания о [не]зависимости могут не соответствовать фактическому положению дел. Если, условно говоря, в начале модуля вы случайно переопределите операцию "+", то конец модуля от этого тоже пострадает.
GospodinKolhoznik
16.02.2025 09:31Если Вася правит функции, необходимые Пете, то он может что то сломать из функций Пети. И при этом не важно в каких модулях эти функции лежат.
Если Вася правит только те функции, которые Петя не использует, то он ничего у Пети не сломает. И опять не имеет значение каких модулях эти функции находятся.
Такие дела))
vadimr
16.02.2025 09:31Я привёл конкретный пример.
GospodinKolhoznik
16.02.2025 09:31Вы, несомненно что то читали про модульную организацию. Возможно даже что то слышали про архитектурные слои. Но такое чувство, что не совсем понимаете зачем оно нужно и как должно быть организовано.
Ок, есть Вася у него есть свои функции, есть Петя, у него свои. Давайте положим все функции Васи в один Модуль, а функции Пети в другой и они друг другу ничего не сломают. Да? А потом приходит Ииигорь! Игорь говорит - мне нужны для работы вот те 25 функций Васи и 30 функций от Пети. Куда их класть? А потом появляется Наташа и заявляет, что ей нужны функции от Васи, от Пети, от Игоря и ещё куча всего, в том числе и из сторонних репозиториев. И прекрасная архитектура совсем сломалась...
vadimr
16.02.2025 09:31Но такое чувство, что не совсем понимаете зачем оно нужно и как должно быть организовано.
Куда уж мне.
Ок, есть Вася у него есть свои функции, есть Петя, у него свои. Давайте положим все функции Васи в один Модуль,
Заметим, я этого не предлагал.
а функции Пети в другой и они друг другу ничего не сломают. Да? А потом приходит Ииигорь! Игорь говорит - мне нужны для работы вот те 25 функций Васи и 30 функций от Пети. Куда их класть?
В каком смысле куда класть? Эти функции как были, так лежат в модулях Васи и Пети.
dykyi_roman Автор
16.02.2025 09:31Возможно тут имелось ввиду куда ложить функционал который агрегирует работу текущей функциональности. Тогда это можно решить на уровне выше. Если это бизнес-логика и нам нужна координация внутри домена, то это можно сделать в UseCase. Если же это композиция нескольких модулей, то можно сделать через фасад отдельного модуля.
dykyi_roman Автор
16.02.2025 09:31Правильное применение DDD и чистой архитектуры решает эту проблему.
Код должен группироваться по bounded context’ам, а не по людям. Если Вася и Петя работают над разными бизнес-сущностями, их код логично разделять, но если у них общие задачи — значит, их код должен находиться в одном контексте.
Если Игорю нужны 25 функций Васи и 30 функций Пети, он не должен напрямую использовать их модули. Вместо этого можно выделить абстракции (интерфейсы), которые предоставляют нужные функции, не привязывая код жестко к модулям.
-
Наташа не должна тянуть весь код Васи, Пети и Игоря. Вместо этого можно создать слой API или фасад, который предоставляет только нужные ей функции.
Это позволит избежать хаоса и сохранить модульность, так как Наташа будет работать только с контрактами, а не с конкретной реализацией.
Если у нас есть четкие слои (Domain, Application, Infrastructure) и фичи (Package by Feature), архитектура останется устойчивой, даже если добавится новый разработчик или новая функциональность.
santjagocorkez
16.02.2025 09:31А если 2 сущности А и Б, где Б зависит от А, значит в любом случае для Б доступна видимость А
Не всегда. Если А и Б в одном модуле, то Б имеет доступ к internal (C#) потрохам А, а если в разных, то Б может пользоваться только public. Если, конечно, не лезть в интроспекцию.
AlexGorky
16.02.2025 09:31Да, надо как-то комбинировать.
Например, бизнес-центр в городе - один. И все туда едут на работу утром.
А заводы - в другом месте (желательно за городом).
Будет не очень комфортно, если в каждом районе, кроме аптеки и школы будет завод?
vadimr
16.02.2025 09:31Может быть ссылки на методы или данные из другого модуля вызываются гораздо дольше чем аналогичные ссылки в своем модуле?
Во многих реализациях языков программирования (наиболее распространённым примером является C/C++) так и есть. Вызов из своего модуля такой компилятор может, скажем, заинлайнить, а из другого – нет.
vadimr
16.02.2025 09:31Обычно на нижнем уровне располагаются универсальные примитивы, выделенные по принципу by layer (условно говоря, то, что разработчики системы программирования забыли положить в системную библиотеку – да собственно и сама системная библиотека), а над ними – предметно-ориентированные модули по принципу by feature.
Dhwtj
16.02.2025 09:31В одном случае by layer проще сделать DRY, но больше риск зависимостей. Удобно, когда 100500 похожих функций.
В данном случае всё изолированно. Удобно, когда много предметных областей и/или программистов
В общем то и вся разница.
Sergey_Kh
В реальной жизни выглядит так, как будто package by layer удобнее.
Ну в самом деле, отдельная коробка носков для ресторана, отдельная для работы, отдельная для встречи с друзьями это перебор)
Или на кухне отдельная соль для пиццы, отдельная соль для салатов, отдельная соль для супов.
Ну вы поняли - большое количество сущностей может быть использовано в разных features
dykyi_roman Автор
.
dykyi_roman Автор
тут как посмотреть) В целом имеет место быть обоим подходам. Как и в программировании все зависит от ситуации.
Я не хотел бы жить в городе где все школы в одном районе, аптеки в другом, а магазины в третем. Тут package by layer никак не может быть применен.
До того как я пошел заниматься в тренажерный зал у меня например вещи были упорядочены в package by layer. Это кажется логично и удобно. Но когда я начал ходить в зал. у меня появились свое отдельное полотенце для плавания, трусы и шапочка и они у меня никогда не лежат в общем гардеробе.
Также в магазинах одежды мы можем заметить упорядоченые вещи по типу - package by layer. Но если мы зайдем в шоу-рум там ты увидешь готовые луки - package by feature.
Если на кухне несколько поваров и каждому нужна своя рабочая зона для готовки еды, то удобно что все приборы и ингредиенты будут в районе этой зоны и тогда они у каждого свои, тогда package by feature выглядит идеальным выбором. Я это знаю так как у меня Брат повар) Но! если у нас повар один или зона она для готовки еды маленькая, то в этом случаи больше подойдет - package by layer.
Sergey_Kh
Согласен с вами, нужно комбинировать оба подхода в зависимости от ситуации.
DExploN
В реальной жизни, задачи касаются какой-то задачи и области. Например, задача добавить цыпленка в меню ресторана. И когда я ее выполняю, кораздо удобнее видеть только сущности ресторана, сервисы ресторана, репозитории ресторана.
А не искать среди работы,ресторана,друзей, свадьбы, подработки