Clean architecture

0

Jeden z portali rekrutacyjnych przetłumaczył ten artykuł: https://medium.com/slalom-build/clean-architecture-with-java-11-f78bba431041
Mam kilka pytań do tego schematu.
Zysk opiera się na wykorzystaniu modułów do izolacji warstw, gdzie warstwy centralne nie wiedzą o sposobie w jaki zostaną użyte (czyli na moje zwykłe Liskov Substitution Principle wyniesione na poziom warstwy). W warstwie use case widać taką metodę:

	public Optional<User> findById(final String id) {
		return repository.findById(id);
	}

Gdzie definicja User jest w warstwie encji a o repository wiemy tyle, że "jest w innym module, nie przejmuj się". I tutaj pojawia się moja zagwozdka: Jeżeli zewnętrzny "nie przejmuj się" moduł zwraca obiekt typu User, to musi być zależnym od warstwy encji, podobnie jak moduł przypadków użycia. Na czym polega wartość stworzenia dodatkowego modułu? Czy chodzi o to, że moduł z repository ma wymuszone granice czego może, a czego nie może użyć + fizyczne wyrzucenie implementacji dostępu do danych z logiki biznesowej?

Jak do powyższego ma się

Any layer can only reference a layer below it and know nothing about what’s going on above.

Jeżeli encja User jest wypychana aż do samego endpointu i ma spore szanse stać się jednocześnie DAO?

Gdzie w tym wszystkim podziały się interface'y? Uproszczenie artykułu, czy wyszły z mody?

Czy clean architecture to kolejne buzz word, artykuł przekłamuje genialną ideę, czy ja nie ogarnąłem jej doniosłości i czepiam się głupot?

1

Tutaj chodzi o Dependency Inversion Principle - warstwa wyższa zależy od interfejsu, a nie od implementacji w warstwie niższej. Dzięki temu przybliżasz się do „czystej domeny”. Używając podziału na moduły jdk9 uniemożliwiasz złamanie tej zasady już na etapie kompilacji.

Generalnie można to samo osiągnąć ArchUnitem na etapie testów, nie potrzeba do tego jdk9 (nie spotkałem się, żeby ktoś używał jigsawa).

Ten biedny User jest częścią kontraktu, jaki musi spełnić repository. Zwracanie encji z repository jest jak najbardziej OK. Czy jest dalej zwracane z kontrolera (nie powinno być), to już inna dyskusja.

Gdzie w tym wszystkim podziały się interface'y? Uproszczenie artykułu, czy wyszły z mody?

Przecież są zastosowane interfejsy do realizacji portów.

Czy clean architecture to kolejne buzz word, artykuł przekłamuje genialną ideę, czy ja nie ogarnąłem jej doniosłości i czepiam się głupot?

Both are true :) z jednej strony to jest izomorficzne do portów/adapterów, więc nic nowego, z drugiej strony nie zrozumiałeś clue.

0

W artykule jest stwierdzenie

Note that the interface is also known as a port

Ale implementacja opiera się na klasie public final class CreateUser {.... więc niezależnie od tego jak wstrzykiwana jest implementacja Repository o jakimś łatwym zastąpieniu jednej zależności inną raczej nie ma mowy.

Czy clue to wymuszenie izolacji warstw? Konkretnie jeżeli jest taka definicja modułu:

module slalom.example.domain {
	exports com.slalom.example.domain.entity;
	exports com.slalom.example.domain.port;
	exports com.slalom.example.domain.exception;
}

To bez zmiany perymetru modułu nie da się w User użyć np. repository, czy UseCase?

2

Może prościej: ma się nie dać wstrzyknąć do use case konkretnej implementacji repozytorium. Zobacz, że eksportujesz porty (interfejsy), a nie implementacje.

0

Dobra, wszedłem do repozytorium i stało się to sporo jaśniejsze, dzięki.

1 użytkowników online, w tym zalogowanych: 0, gości: 1