Package By Feature
От: Буравчик Россия  
Дата: 06.03.20 16:09
Оценка:
Как вы формируете пакеты по фичам? Расскажите про свой опыт

Я про "Package by feature, not layer"
http://www.javapractices.com/topic/TopicAction.do?Id=205

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

Вот есть слои:
— domain model (data классы)
— domain services (use cases, полезные действия)
— классы работы с инфраструктурой (database, внешние сервисы)
— классы для интерфейсов (REST API, скрипты)

Что из этого бьется по фичам, а что остается слоями?
Какими правилами руководствуетесь при выделении фич?
Best regards, Буравчик
Re: Package By Feature
От: Буравчик Россия  
Дата: 11.03.20 17:37
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Что из этого бьется по фичам, а что остается слоями?


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

Мне кажется, по фичам стоит группировать классы domain model (data-классы), domain services, а также классы, работающие с инфраструктурой, специфичные для этой фичи (например, DAO для конкретной фичи или внешний сервис, нужный только этой фиче).

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

Классы для интерфейса к программе (API, CLI, GUI) нет смысла группировать по фичам, т.к. их структура может совсем не соответствовать структуре пакетов фич. Хотя частенько пересечения бывают, и довольно большие
Best regards, Буравчик
Re: Package By Feature
От: Quadri  
Дата: 11.03.20 20:10
Оценка: +1
Здравствуйте, Буравчик, Вы писали:

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


Для лучшего понимания проекта и вообще навигации я бы хотел иметь переключатель по слоям/по фичам.
Re[2]: Package By Feature
От: Буравчик Россия  
Дата: 11.03.20 21:53
Оценка:
Здравствуйте, Quadri, Вы писали:

Q>Здравствуйте, Буравчик, Вы писали:


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


Q>Для лучшего понимания проекта и вообще навигации я бы хотел иметь переключатель по слоям/по фичам.


Да, было бы круто, если бы IDE могла такое делать.

Кстати, этом момент тоже говорит в пользу деления пакетов по фичам (если выбирать только один вариант — фичи или слои).
Т.к. слои можно понять из названий пакетов/классов. И по имени даже найти их в IDE. А вот по фичам поделить — только вручную.
Best regards, Буравчик
Re[2]: Package By Feature
От: Quadri  
Дата: 12.03.20 09:34
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Судя по отсутствию обсуждения все делят пакеты по слоям, по старинке


Б>Мне кажется, по фичам стоит группировать классы domain model (data-классы), domain services, а также классы, работающие с инфраструктурой, специфичные для этой фичи (например, DAO для конкретной фичи или внешний сервис, нужный только этой фиче).


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


Б>Классы для интерфейса к программе (API, CLI, GUI) нет смысла группировать по фичам, т.к. их структура может совсем не соответствовать структуре пакетов фич. Хотя частенько пересечения бывают, и довольно большие


Вот это самый большой минус деления по фичам — оно не получается "чистым" и становится перемешанным, в то время как деление по слоям получается более "чистым".
Re[3]: Package By Feature
От: · Великобритания  
Дата: 24.03.20 09:48
Оценка: 1 (1)
Здравствуйте, Quadri, Вы писали:

Б>>Классы для интерфейса к программе (API, CLI, GUI) нет смысла группировать по фичам, т.к. их структура может совсем не соответствовать структуре пакетов фич. Хотя частенько пересечения бывают, и довольно большие

Q>Вот это самый большой минус деления по фичам — оно не получается "чистым"
Да, приходится думать прежде чем делать.

Q>и становится перемешанным,

Рефакторинг же — если перемешалось, то перемещаем чтобы разделить.

Q>в то время как деление по слоям получается более "чистым".

Вот это самый большой минус деления по слоям — такое деление выполняется автоматически, и никакого смысла не несёт, чистая формальность "так все делают, значит так надо". В итоге всё равно приходится игнорировать такие packages как информационный мусор, уж лучше бы всё в одном package лежало. Только вред, никакой пользы.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re: Package By Feature
От: diez_p  
Дата: 25.03.20 11:24
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Как вы формируете пакеты по фичам? Расскажите про свой опыт


Б>Я про "Package by feature, not layer"

Б>http://www.javapractices.com/topic/TopicAction.do?Id=205

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


Б>Вот есть слои:

Б>- domain model (data классы)
Б>- domain services (use cases, полезные действия)
Б>- классы работы с инфраструктурой (database, внешние сервисы)
Б>- классы для интерфейсов (REST API, скрипты)

Б>Что из этого бьется по фичам, а что остается слоями?

Б>Какими правилами руководствуетесь при выделении фич?

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

Если коротко, то фича это точно такой же компонент приложения в слое бизнес логики, если говорить о, так называемой классической "слоеной" архитектуре проекта. (Database, Persistence, Services, Business, Presentation)
При использовании того или иного подхода всегда надо задумываться: "а за чем?" "Что я получаю в конкретном месте вот этого проекта?" Я не против некоторых инвестиций в коде, в виде "а давайте сделаем наперед", но как и в любой инвестиции надо знать вероятность и срок окупаемости и плата в текущем временем за что-то там в будущем, в общем с этим надо быть аккуратным и только опыт тут советчик.


Слой или фича в физическом представлении(т.е. размещении кода на диске) — абстрактны, т.к. для конкретной фичи в подлежащих слоях может быть запилен необходимый функционал и использоваться только конкретной фичей.
Физически в коде я выделяю компонент — закоченный блок кода с публичным контрактом и внутренней реализацией. На начальном этапе публичность контракта уомпонента может быть весьма условной, разделение классов на package/public, помещение классов в отдельное дерево подпапок. При размещении прежде всего важна семантика, а не физическое ограничение, т.к. именно семантика позволяет понять идею кода. До тех пор пока нет необходимости что-то разграничивать или изолировать, пользуюсь уровнем достаточной декомпозиции и распределение обязанностей. Это не значит что buttonOnСlick а внутри new dbConnection().open(). Но в тривиальном варианте будет пара компонентов (могут даже состоять из одного класса), среди которых будет распределена вся работа. Критерий такой, что декомпозиция и интерфейсы должны позволять легко понимать саму идею кода и легкую его модификацию при потребности.

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

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

com.app.doctor
com.app.drug
com.app.patient
com.app.presription
com.app.report
com.app.security
com.app.webmaster
com.app.util
and so on...

com.app.action
базовая функциональность контроллера
com.app.model
базовая функциональность модели
Которая возможно будет ходить и в auth и в logging
com.app.auth
com.app.logging
com.app.dao
EntityConverter
mySql
mysqlstaff
oracle
oracleStaff

com.app.util <-- помойка, пакет выкинуть и разложить/распределить классы более прецезионно
Re[2]: Package By Feature
От: · Великобритания  
Дата: 25.03.20 12:46
Оценка:
Здравствуйте, diez_p, Вы писали:

_>Никогда не придерживался како-то одного стиля, всегда комбинировал.


_>com.app.doctor

...
_>com.app.action
_> базовая функциональность контроллера
_>com.app.model
_> базовая функциональность модели
...

Это и есть чистый Package By Feature, нет никаких комбинаций. Эти "базовые функциональности" просто не относятся к фичам самого приложения и не являются слоями, а просто фичи сами по себе в том смысле что их фактически можно отрезать в независимые библиотеки и даже зареюзать из других приложений. Другими словами, какой-нибудь там java.sql вполне себе фича JDK, поэтому почему бы не быть com.app.sql.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[3]: Package By Feature
От: diez_p  
Дата: 25.03.20 13:17
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, diez_p, Вы писали:


_>>Никогда не придерживался како-то одного стиля, всегда комбинировал.


_>>com.app.doctor

·>...
_>>com.app.action
_>> базовая функциональность контроллера
_>>com.app.model
_>> базовая функциональность модели
·>...

·>Это и есть чистый Package By Feature, нет никаких комбинаций. Эти "базовые функциональности" просто не относятся к фичам самого приложения и не являются слоями, а просто фичи сами по себе в том смысле что их фактически можно отрезать в независимые библиотеки и даже зареюзать из других приложений. Другими словами, какой-нибудь там java.sql вполне себе фича JDK, поэтому почему бы не быть com.app.sql.


Тогда я не понимаю что такое package by Layer
Вполне допустимо когда пакеты будут com.app.business.feature1, com.app.business.feature2 либо com.app.service.service1, com.app.service.service2.
Хотя изначально можно и не выделять отдельное имя для feature1, feature2.
Отредактировано 25.03.2020 13:24 diez_p . Предыдущая версия . Еще …
Отредактировано 25.03.2020 13:20 diez_p . Предыдущая версия .
Re[4]: Package By Feature
От: · Великобритания  
Дата: 25.03.20 13:38
Оценка:
Здравствуйте, diez_p, Вы писали:

_>Тогда я не понимаю что такое package by Layer

_>Вполне допустимо когда пакеты будут com.app.business.feature1, com.app.business.feature2 либо com.app.service.service1, com.app.service.service2.
Это когда у тебя классы размещаются по архитектурным слоям:
com.app.dao.DoctorDao
com.app.dao.PatientDao
com.app.bl.DoctorService
com.app.bl.PatientService
com.app.exception.PatientNotFoundException
com.app.servlets.PatientServlet
com.app.servlets.DoctorServlet
и т.п.
Пошло из лихих 90-х, когда приложения писали на XML и можно было регекспы ставить для AOP, магия component-scan и прочий кошмар. Мол, "наложим декларативно транзакции на все методы классов попадающих под маску 'com.app.bl.*'".
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re: Package By Feature
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 25.03.20 16:23
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Как вы формируете пакеты по фичам? Расскажите про свой опыт


Б>Я про "Package by feature, not layer"

Б>http://www.javapractices.com/topic/TopicAction.do?Id=205

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


Б>Вот есть слои:

Б>- domain model (data классы)
Б>- domain services (use cases, полезные действия)
Б>- классы работы с инфраструктурой (database, внешние сервисы)
Б>- классы для интерфейсов (REST API, скрипты)

Б>Что из этого бьется по фичам, а что остается слоями?

Б>Какими правилами руководствуетесь при выделении фич?


Чтобы можно было делать Package By Feature нужно чтобы платформа умела делать Deploy By Feature.
То есть:
1) Ты задеплоил пакет на сервер
2) НЕЧТО проверило содержимое пакета на конфликты с другими пакетами
3) НЕЧТО поняло как объединить изменения СУБД с другими изменениями других пакетов и накатило изменения на базу
4) НЕЧТО подгрузило библиотеки кода в процесс и прокинуло необходимые вызовы
5) НЕЧТО опубликовало в ФС файлы нужные для работы
6) Нечто опубликовало веб-сервисы на сервере

Короче все упирается в это самое НЕЧТО. В .net есть Orchard Core Framework для этого дела, но все еще не релиз и вообще не supported.
Что есть у других платформ на этот счет — хз.

Если этого НЕЧТА не существует, то "Package by feature, not layer" превратится в "Package by feature and layer" и рукопашное разруливание конфликтов.
Re[2]: Package By Feature
От: · Великобритания  
Дата: 26.03.20 10:47
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Чтобы можно было делать Package By Feature нужно чтобы платформа умела делать Deploy By Feature.

G>То есть:
G>1) Ты задеплоил пакет на сервер
Ты что-то попутал, имхо. package в данном случае это что-то вроде namespace в С++/C#. А ты похоже пишешь о assembly или bundle.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[3]: Package By Feature
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 26.03.20 11:55
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, gandjustas, Вы писали:


G>>Чтобы можно было делать Package By Feature нужно чтобы платформа умела делать Deploy By Feature.

G>>То есть:
G>>1) Ты задеплоил пакет на сервер
·>Ты что-то попутал, имхо. package в данном случае это что-то вроде namespace в С++/C#. А ты похоже пишешь о assembly или bundle.
Тогда вообще непонятно о чем разговор.
Код работает одинаково, независимо от того, в каком он неймспейсе.
Re[4]: Package By Feature
От: · Великобритания  
Дата: 26.03.20 14:48
Оценка: +2
Здравствуйте, gandjustas, Вы писали:

G>·>Ты что-то попутал, имхо. package в данном случае это что-то вроде namespace в С++/C#. А ты похоже пишешь о assembly или bundle.

G>Тогда вообще непонятно о чем разговор.
G>Код работает одинаково, независимо от того, в каком он неймспейсе.
При таком подходе вообще непонятно зачем эти неймспейсы, packages и layers вообще. Берёшь и всё засовываешь в main() — работать будет одинаково, доказано Тьюрингом.

Впрочем, в java есть ещё package-private access modifier. Т.е. небольшая разница есть с т.з. компилятора.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.