Статьи

Пакет за слоем для проекта Spring устарел

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

Прежде всего, позвольте мне кратко описать каждый подход.

«Пакет за слоем» («Папка по типу» в мире, отличном от Java)

Эта структура проекта группирует файлы исходного кода в пакеты / каталоги на основе уровня архитектуры, к которому они относятся:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
.
└── net
    └── lkrnac
        └── blog
            ├── Application.java
            ├── persistence
            │   ├── ProjectRepository.java
            │   └── UserRepository.java
            ├── dto
            │   ├── ProjectDto.java
            │   └── UserDto.java
            ├── model
            │   ├── Project.java
            │   └── User.java
            ├── service
            │   ├── ProjectService.java
            │   └── UserService.java
            └── web
                ├── ProjectController.java
                └── UserController.java

«Пакет по функции» («Папка по функции» в мире, отличном от Java)

С другой стороны, этот подход группирует файлы, принадлежащие определенной функции в системе:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
.
└── net
    └── lkrnac
        └── blog
            ├── Application.java
            ├── project
            │   ├── ProjectController.java
            │   ├── ProjectDto.java
            │   ├── Project.java
            │   ├── ProjectRepository.java
            │   └── ProjectService.java
            └── user
                ├── UserController.java
                ├── UserDto.java
                ├── User.java
                ├── UserRepository.java
                └── UserService.java

тенденции

Эта тема интересовала меня давно. Когда я гуглю «пакет за слоем» против «пакет по функции» или «папка по типу» против «папка по функции», мне кажется, что растет число сторонников структуры «по функциям». Я тоже в этом лагере.

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

Весенняя структура проекта

Так как есть много литературы о плюсах и минусах каждого подхода, я сосредоточусь на последствиях для проекта Spring.

Традиционная структура создания приложений Spring CRUD (если ваше внутреннее приложение не использует Spring Data REST) ​​делится на 3 уровня: веб / служба / постоянство. Подавляющее большинство Java / Spring проектов, над которыми я работал, следовали этой структуре.

Связь

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

Когда вы пишете сигнатуру для класса в пакете со слоистым проектом, какое ключевое слово является первым? Могу поспорить, что это публично. Модификатор общего доступа помогает отделить? Я думаю, никто не ответил бы да на этот вопрос.

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

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

пересчет

Что произойдет, если проект начнет иметь более 10 классов в слое web / service / persistence? Разработчики склонны группировать классы в подпакеты. Но как они классифицируют их? По моему опыту, это в основном основано на функциях. Поэтому мы часто можем найти такую ​​структуру в более крупных проектах:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
.
└── net
    └── lkrnac
        └── blog
            ├── Application.java
            ├── dao
            │   ├── ...other repositories...
            │   ├── ProjectRepository.java
            │   └── user
            │       ├── UserRepository.java
            │       └── UserRoleRepository.java
            ├── dto
            │   ├── ...other DTOs...
            │   ├── ProjectDto.java
            │   └── user
            │       ├── UserDto.java
            │       └── UserRoleDto.java
            ├── model
            │   ├── ...other models...
            │   ├── Project.java
            │   └── user
            │       ├── User.java
            │       └── UserRole.java
            ├── service
            │   ├── ...other services...
            │   ├── ProjectService.java
            │   └── user
            │       ├── UserRoleService.java
            │       └── UserService.java
            └── web
                ├── ...other controllers...
                ├── ProjectController.java
                └── user
                    ├── UserController.java
                    └── UserRoleController.java

Разве это не очевидное безумие?

Будущее доказательство

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

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

вывод представляется

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

Смотрите оригинальную статью здесь: Пакет за слоем для проекта Spring устарел

Мнения, высказанные участниками Java Code Geeks, являются их собственными.