Папка по типу или папка по функции

59

Я использую руководство по стилю AngularJS. В этом руководстве есть стиль, который называется folder-by-featureвместо folder-by-type, и мне действительно любопытно, каков наилучший подход (в этом примере для Java)

Допустим, у меня есть приложение, в котором я могу получать Users & Pets, используя сервисы, контроллеры, репозитории и объекты домена ofcourse.

Принимая стили папок -....., у нас есть два варианта нашей структуры упаковки:

1. Папка по типу

com.example
├── domain
│    ├── User.java
│    └── Pet.java
├── controllers
│    ├── UserController.java
│    └── PetController.java
├── repositories
│    ├── UserRepository.java
│    └── PetRepository.java
├── services
│    ├── UserService.java
│    └── PetService.java
│   // and everything else in the project
└── MyApplication.java

2. Папка за функцией

com.example
├── pet
│    ├── Pet.java
│    ├── PetController.java
│    ├── PetRepository.java
│    └── PetService.java
├── user
│    ├── User.java
│    ├── UserController.java
│    ├── UserRepository.java
│    └── UserService.java
│   // and everything else in the project
└── MyApplication.java

Что было бы хорошим подходом, и каковы аргументы для этого?

Элле
источник
1
Я не знаю @Laiv. Язык / структура действительно влияют на ответ? Несмотря на это, другой вопрос, безусловно, актуален.
RubberDuck
1
Тогда я должен отредактировать свой ответ. И да, это возможный дубликат
Laiv
2
Я никогда не понимал преимущества папок по типу. Если я работаю над билетом, относящимся к функции Pet, я, вероятно, выиграю от местоположения Pet, контроллера, хранилища и сервиса. В какой ситуации мне понадобятся все контроллеры, кроме представлений, репозиториев или сервисов?
Александр
2
Кажется, никто не упомянул, что пакеты в Java - это не просто папки; они также влияют на доступ к содержащимся классам. По этой причине, пакет за слоем / тип может фактически обеспечить некоторое семантическое значение в Java.
Ангус Голдсмит

Ответы:

69

Папка по типу работает только в небольших проектах. Папка за функцией превосходит в большинстве случаев.

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

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

Во-первых, вы можете придерживаться общих соглашений об именах, которые подразумевают типичность имени файла. Например, популярное руководство по стилю AngularJS Джона Папы содержит следующее:

Правила именования

  • Используйте согласованные имена для всех компонентов, следуя шаблону, который описывает функцию компонента, а затем (необязательно) его тип. Мой
    рекомендуемый шаблон - feature.type.js. Есть два названия для большинства
    активов:

    • имя файла (avengers.controller.js)
    • имя зарегистрированного компонента с Angular (AvengersController)

Во-вторых, вы можете комбинировать стили папок по типам и папок по функциям в папку по функциям:

com.example
├── pet
|   ├── Controllers
│   |   ├── PetController1.java
|   |   └── PetController2.java
|   └── Services
│       ├── PetService1.java
│       └── PetService2.java
├── user
|   ├── Controllers
│   |   ├── UserController1.java
│   |   └── UserController2.java
|   └── Services
│       ├── UserService1.java
│       └── UserService2.java
Восстановить Монику
источник
1
Это был тот самый гид по стилю johnpapa, о котором я говорил :-)
Jelle
1
Иногда (чаще, чем мы думаем) мы добавляем слишком сложность к вещам, которые должны были быть легкими. Наименование и упаковка - вот некоторые из этих вещей. Лучший совет - будь проще. Смешение обоих имеет как преимущества, так и недостатки обоих подходов.
Laiv
1
@Laiv В примере, который я привел, я согласен с его излишним, но в большинстве моих реальных бизнес-случаев, когда каждая папка типов может легко содержать 10-20 файлов, я думаю, что это очень полезно, потому что общая папка функций будет иметь порядка 50 файлы в противном случае.
Восстановить Монику
6
подделка, спасибо айфон авто-исправить! Я имел в виду «говорить».
Желе
2
@Chaotic Этот пример слишком тривиален, чтобы начать говорить о специфике, но в тех случаях, когда у вас есть фрагменты, которые используются в нескольких компонентах, тогда это, вероятно, должен быть собственный компонент, от которого зависят другие компоненты.
Восстановить Монику
26

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

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

Майкл Боргвардт
источник
10
Я бы добавил, что в папках по функциям проще играть с классами и методами областей (защищен, упакован, ...).
Laiv
Для небольших проектов у вас может быть только одна особенность. Гораздо проще организовать по типу в этом сценарии.
аааааа
Например, Grails принудительно
устанавливает
17

Работа с пакетами по функциям отличается высокой модульностью и согласованностью . Это позволяет нам играть с областью компонентов. Например, мы можем использовать модификаторы доступа для обеспечения LoD и инверсии зависимостей для интеграций и / или расширений.

Другие причины:

  • Более простая навигация по коду
  • Более высокий уровень абстракции
  • Минимизация областей (ограничивающие контексты)
  • Вертикальная модульность

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

Наконец, есть третий вариант. « Пакет за компонентом », который, по словам дяди Боба, кажется лучше согласованным с его принципами упаковки . Если мнение дяди Боба имеет значение или нет, я оставляю вам решать. Я нахожу это интересным, так как это соглашение согласуется с его Чистой Архитектурой, которая мне нравится.

LAIV
источник