Folder według typu lub Folder według funkcji

59

Korzystam z przewodnika po stylu AngularJS. W tym przewodniku jest styl zwany folder-by-featurezamiast folder-by-type, i jestem ciekawy, jakie jest najlepsze podejście (w tym przykładzie dla Javy)

Załóżmy, że mam aplikację, w której mogę odzyskiwać użytkowników i zwierzęta, korzystając z usług, kontrolerów, repozytoriów i obiektów domeny oczywiście.

Biorąc pod uwagę style sortowania według, mamy dwie opcje dla naszej struktury opakowania:

1. Folder według typu

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. Folder według funkcji

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

Jakie byłoby dobre podejście i jakie są tego argumenty?

Jelle
źródło
1
Nie znam @Laiv. Czy język / struktura naprawdę wpływa na odpowiedź? Niezależnie od tego drugie pytanie jest z pewnością istotne.
RubberDuck,
1
Następnie muszę edytować swoją odpowiedź. I tak, to możliwy duplikat
Laiv
2
Nigdy nie rozumiałem korzyści z sortowania według typu. Jeśli pracuję nad biletem dotyczącym funkcji Pet, prawdopodobnie skorzystałbym z lokalizacji Pet, kontrolera, repozytorium i usługi. W jakiej sytuacji potrzebowałbym kiedykolwiek wszystkich kontrolerów, ale nie widoków, repozytoriów lub usług?
Alexander
2
Wydaje się, że nikt nie wspominał, że pakiety w Javie to nie tylko foldery; wpływają również na dostęp do zawartych klas. Z tego powodu pakiet po warstwie / typ może faktycznie zapewnić pewną wartość semantyczną w Javie.
Angus Goldsmith,

Odpowiedzi:

69

Folder według typu działa tylko w przypadku małych projektów. Folder według funkcji jest lepszy w większości przypadków.

Sortowanie według typu jest w porządku, gdy masz tylko niewielką liczbę plików (powiedzmy poniżej 10 na typ). Jak tylko pojawi się wiele komponentów w swoim projekcie, wszystkie z wieloma plikami tego samego typu, bardzo trudno jest znaleźć rzeczywisty plik, którego szukasz.

Dlatego funkcja sortowania według folderów jest lepsza ze względu na skalowalność. Jednak jeśli folder według funkcji spowoduje utratę informacji o typie elementu, który reprezentuje plik (ponieważ nie ma go już w controllerfolderze, powiedzmy), to również staje się mylące. Są na to 2 proste rozwiązania.

Po pierwsze, możesz przestrzegać typowych konwencji nazewnictwa, które sugerują typowość w nazwie pliku. Na przykład popularny przewodnik po stylu AngularJS Johna Papy ma następujące elementy:

Wskazówki dotyczące nazewnictwa

  • Użyj spójnych nazw dla wszystkich komponentów zgodnie ze wzorcem, który opisuje funkcję komponentu, a następnie (opcjonalnie) jego typ. Mój
    zalecany wzór to feature.type.js. Istnieją 2 nazwy większości
    zasobów:

    • nazwa pliku (avengers.controller.js)
    • zarejestrowana nazwa komponentu w Angular (AvengersController)

Po drugie, możesz łączyć style folderów według typu i folderów według funkcji w folderze według funkcji według typu:

com.example
├── pet
|   ├── Controllers
│   |   ├── PetController1.java
|   |   └── PetController2.java
|   └── Services
│       ├── PetService1.java
│       └── PetService2.java
├── user
|   ├── Controllers
│   |   ├── UserController1.java
│   |   └── UserController2.java
|   └── Services
│       ├── UserService1.java
│       └── UserService2.java
Przywróć Monikę
źródło
1
Przewodnik po stylu johnpapa był właśnie tym, o którym myślałam :-)
Jelle
1
Czasami (częściej niż nam się wydaje) dodajemy zbyt złożoności do rzeczy, które miały być łatwe. Nazewnictwo i pakowanie to tylko niektóre z tych rzeczy. Najlepsza rada jest prosta. Mieszanie obu ma zarówno zalety, jak i wady obu podejść.
Laiv
1
@Laiv W podanym przeze mnie przykładzie zgadzam się na jego nadmiar, ale w większości moich prawdziwych przypadków biznesowych, w których każdy folder typu może łatwo zawierać 10-20 plików, uważam, że jest to bardzo przydatne, ponieważ ogólny folder funkcji miałby rzędu 50 pliki inaczej.
Przywróć Monikę
6
pierdolę, dzięki iPhone'owi autokorekta! Miałem na myśli „rozmowę”.
Jelle,
2
@Chaotic Ten przykład jest zbyt trywialny, aby zacząć mówić o szczegółach, ale w takich przypadkach, w których masz elementy, które są używane w wielu komponentach, prawdopodobnie powinien to być własny komponent, od którego zależą inne komponenty.
Przywróć Monikę
26

To naprawdę nie ma nic wspólnego z omawianą technologią, chyba że użyjesz frameworka, który wymusza na tobie sortowanie według typu w ramach podejścia opartego na konwencjach i konfiguracji.

Osobiście jestem głęboko przekonany, że funkcja sortowania według folderów jest znacznie lepsza i powinna być używana wszędzie, jak to możliwe. Grupuje razem klasy, które faktycznie ze sobą współpracują, podczas gdy folder według typu kopiuje tylko coś, co zwykle jest już obecne w nazwie klasy.

Michael Borgwardt
źródło
10
Dodałbym, że w folderze według funkcji łatwiej jest bawić się zakresami klas i metod (chroniony, pakiet, ...).
Laiv
W przypadku mniejszych projektów możesz mieć tylko jedną funkcję. W tym scenariuszu łatwiej jest zorganizować według typu.
aaaaaa
Na przykład Grails wymusza
sortowanie
17

Praca z pakietami według funkcji wyróżnia się wysoką modułowością i spójnością . Pozwala nam to na zabawę w zakres komponentów. Na przykład możemy użyć modyfikatorów dostępu, aby wymusić LoD i inwersję zależności dla integracji lub rozszerzeń.

Inne powody to:

  • Łatwiejsza nawigacja po kodzie
  • Wyższy poziom abstrakcji
  • Minimalizuj zakresy (konteksty graniczne)
  • Modularyzacja pionowa

Folder po warstwie kładzie zbyt duży nacisk na szczegóły implementacji (jak wspomniał @David), co nie mówi zbyt wiele o aplikacji, nad którą pracujemy. W przeciwieństwie do pakiet po funkcji , pakiet po warstwie zachęca do poziomej modularyzacji. Ten rodzaj modularyzacji sprawia, że ​​praca z elementami przekrojowymi jest trudna i uciążliwa.

Wreszcie jest trzecia opcja. „ Pakiet po komponencie ”, który, jak mówi wujek Bob, wydaje się lepiej dostosowany do jego zasad dotyczących pakietów . Jeśli opinia wuja Boba ma znaczenie, czy nie, pozostawiam to tobie do podjęcia decyzji. Uważam to za interesujące, ponieważ konwencja ta jest zgodna z jego Czystą architekturą, którą lubię.

Laiv
źródło