Podział na pakiety ze względu na warstwy czy funkcjonalność.

Podział na pakiety ze względu na warstwy czy funkcjonalność.
O1
  • Rejestracja:ponad 14 lat
  • Ostatnio:5 dni
0

Witam. Chciałbym zapytań jakie podejście stosujecie w waszych projektach jeśli chodzi o podział na pakiety. Chyba dwa najpopularniejsze podejścia to podział ze względu na warstwy lub funkcjonalność? Nie wiem czy dobrze przetłumaczyłem chodzi mi

Package by feature or layer

Osobiście lepszym podejściem wydaje mi się podział ze względu na funkcjonalność. Mam jednak co do takiego podziału jedną wątpliwość. Gdzie umieszczać wspólne interfejsy dla różnych pakietów? Przykładowo mamy projekt z takimi pakietami:

com.app.clinic

-doctor
--controller
--dao
--domain
--services
--view

-reports
--controller
--dao
--domain
--services
--view

itd.

Gdzie w takim wypadku umieścić te wspólne klasy i interfejsy? Np zarówno pakiet doctor jak i reports ma klasy dao, które mogą implementować jakieś dao generyczne, podobnie mogą być w obu pakietach klasy do walidacji, które implementują wspólny interfejs validator. Gdzie w takim przypadku umieszczać te wspólne klasy?

edytowany 2x, ostatnio: olek1
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

Ze względu na warstwy


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
O1
  • Rejestracja:ponad 14 lat
  • Ostatnio:5 dni
0

Dlaczego preferujesz podział ze względu na warstwy? Mógłbyś uzasadnić? Jak dla mnie podział ze względu na funkcjonalność wydaje się bardziej uporządkowany i łatwiej się w nim odnaleźć.

Mam też jeszcze jedno pytanie dotycząc samego nazywania pakietów bo nie znalazłem jednoznacznej odpowiedzi. Jak nazywać podpakiety, które mają nazwy dłuższe niż pojedyncza nazwa. Przykładowo: network service. Nazywać wtedy pakiet:

com.app.test.networkService
com.app.test.network_service
com.app.test.networkservice

Z tego co wyczytałem w nazwach pakietów nie powinno się stosować camel case, więc pierwsze podejście raczej odpada. Co z kolejnymi stosować znak "_" czy może łączyć kilka wyrazów w jeden? Ale czy nie robi się to wtedy trudne w czytaniu? Może po prostu unikać nazw kilkuczłonowych i zamiast tego nazwać pakiet np. tak:

com.app.test.service (to chyba akurat nie najlepszy pomysł gdyż podpakiety z klasami serwisowymi często się tak nazywają)
com.app.test.network

PI
  • Rejestracja:ponad 9 lat
  • Ostatnio:3 miesiące
  • Postów:2787
0

W sumie takiego sztywnego podziału raczej nie ma. Ale troszkę ciut bardziej w stronę podziału na funkcjonalność

PI
  • Rejestracja:ponad 9 lat
  • Ostatnio:3 miesiące
  • Postów:2787
0

A co do nazywania pakietów to ze spokojem, kolejne wyrazy oddzielaj kropką czyli jak masz frazę "something big" to masz pakiet something.big

O1
  • Rejestracja:ponad 14 lat
  • Ostatnio:5 dni
0

@Pinek No tak myślałem, że można by także oddzielać kropką, ale zastanawiałem się bo wtedy robi się taki pusty pakiet something w którym nie będzie żadnej klasy, a tylko kolejny podpakiet big.

Domyślam się, że takiego sztywnego podziału nie ma, ale co zrobić np. w sytuacji opisanej przeze mnie w pierwszym poście ze wspólnymi klasami? Jak mam pod pakiety doctor i report i oba mają klasy dao i jakieś walidatory. Gdzie wtedy umieścić klasy nadrzędne wspólne dla kilku pakietów? Takie jak generyczne dao czy interfejs validator?

Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
2
  1. Na wspólne elementy zrób osobny moduł, jakieś Commons czy Infrastructure
  2. Z podziałem nie ma prostej jednoznacznej odpowiedzi, czasem lepiej dzielić względem warstwy, a czasem względem funkcjonalności. Podział warstwami pasuje do monolitycznych aplikacji i utrudnia trochę rozbudowę do dodanie czegoś wymaga zmian we wszystkich warstwach. Jest też sensowne jeśli aplikacja ma dość wąski zakres funkcji (nie znaczy to że aplikacja jest prosta!). Dla aplikacji z mocno rozbudowaną warstwą logiki biznesowej i tak konieczne będzie podzielenie tej logiki na osobne moduły. Do tego dochodzi też kwestia ponownego użycia - możesz importować sobie jeden moduł jako bibliotekę, zamiast importować całej aplikacji.

"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
Koziołek
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:około miesiąc
  • Lokalizacja:Stacktrace
  • Postów:6821
1

Aplikacja dzieli się na moduły, a te dzielą się na warstwy. Współczesne IDE nie będą strzelać fochów jak zaciągniesz 20 modułów. Zatem dzielisz projekt na moduły pod kątem funkcjonalności, co efektywnie wytworzy ci moduły w rodzaju:

  • Commons – tu lądują wszelkie ogólne interfejsy, tu podłączasz zależności do np. JPA API.
  • Utils – gdzie wylądują klasy typu StringUtil, DateFormatter itp. Jest to też miejsce gdzie podłączasz zależności typu Guava
  • API – gdzie umieszczasz interfejs kliencki aplikacji

Do tego każda funkcjonalność ma własny moduł, który gada z innymi modułami za pomocą jakiegoś API lub za pomocą komunikatów po ESB (jak mała apka użyj Guava ESB).


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
O1
  • Rejestracja:ponad 14 lat
  • Ostatnio:5 dni
0

@Koziołek nie wiem czy dobrze zrozumiałem, mógłbyś to bardziej rozwinąć na moim przykładzie z pierwszego postu? Czy w takim podziale jak Ty zaprezentowałeś moje pakiety doctor i reports znajdowałyby się w module API a tam podzielone ze względu na funkcjonalności? Czy może same stanowiłyby osobne moduły?

Wyglądałoby to mniej więcej tak:

  • Moduł Commons: wrzucam tutaj te wspólne interfejsy i klasy typu generyczne dao, walidator itp.

  • Moduł Utils: to tak jak napisałeś klasy narzędziowe typu StringUtil czy DateFormatter, zależności do Guavy, Apache Commons.

  • Moduł API: tutaj wrzucam te wszystkie swoje klasy dzieląc na funkcjonalności, jak w pierwszym poście

-doctor
--controller
--dao
--domain
--services
--view

-reports
--controller
--dao
--domain
--services
--view

edytowany 3x, ostatnio: olek1
LukeJL
  • Rejestracja:około 11 lat
  • Ostatnio:minuta
  • Postów:8399
1

Wydaje mi się, że to zależy od tego czy programiści pracują warstwami czy funkcjonalnościami.

Jeśli biznes wymaga od programistów dostarczania kolejnych funkcjonalności, jeśli taski są zdefiniowane w formie funkcjonalności, jeśli commity do repo są w postaci całych funkcjonalności, to... no, to moim zdaniem nie ma sensu się bawić w podział plików warstwami, bo będzie to podział zakłamany.

np. Ruby on Rails. Tam się dzieli projekt na katalogi, gdzie każdy katalog to inny rodzaj pliku (osobny katalog dla szabonów HTML, osobny dla kodu Ruby, który renderuje te szablony, osobny katalog na CSS, osobny katalog na JS) to efekt jest taki, że pracując nad jedną rzeczą, nad jednym komponentem, musiałem przeskakiwać po 4 czy więcej katalogach, i wszystko mi się mieszało.

Tak samo niektóre projekty w AngularJS, gdzie się dzieli na katalogi directives, templates, services, styles, co jest o tyle niefunkcjonalne, że i tak się pracuje potem na tym komponentami, a nie warstwami. Edytuje się jednocześnie templatkę HTML, CSS, dyrektywę, kontroler, więc tutaj raczej jest dużo lepiej jak masz jeden katalog z komponentem X, gdzie masz wszystko związane z komponentem X, wtedy nie musisz latać po całym projekcie, tak jak tutaj: https://scotch.io/tutorials/angularjs-best-practices-directory-structure

Jednak tu mi się wydaje, że potrzeba pewnej refleksji i nie kopiowania bezwiednie schematów (bo niestety ludzie zobaczą to w jakimś tutorialu albo ściągną w jakimś boilerplate i potem już tak zostaje, bo nie pomyślą, że można inaczej.

Z drugiej strony jeśli aplikacja ma wyraźną architekturę warstwową, to wtedy oczywiście podział katalogów na warstwy ma sens. Podział na warstwy jest fajny, jeśli faktycznie istnieje coś takiego w projekcie (w przypadku AngularJS to ciężko powiedzieć - z jednej strony serwisy są oddzielną warstwą, ale już np. zestaw dyrektywa+templatka HTML+styl CSS to dla mnie po prostu części jednego "komponentu", więc po co to dzielić sztucznie?).

Czyli w skrócie - uważam, że struktura katalogów powinna odzwierciedlać rzeczywistość/potrzeby danego projektu, a nie być kopiowaniem bezmyślnie cudzych praktyk.


Koziołek
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:około miesiąc
  • Lokalizacja:Stacktrace
  • Postów:6821
1

W twoim przypadku nie ma API, ale kilka osobnych modułów typu reports, doctor itp. Przy czym moduł reprezentuje funkcjonalność, a nie fragment modelu domenowego. Ten można wywalić do commons, albo domain. Zatem reports „brzmi” ok, ale doctor pachnie mi próbą modularyzacji kawałka domeny (jakiegoś bytu domenowego), a nie funkcjonalności. Chyba, że w doctors masz coś w rodzaju wizyty, specjalizacje, grafik pracy (o ile to pet clinic).


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)