誀解のないクリヌンアヌキテクチャ

円をブロックに倉える


䞀芋したずころ、 Clean Architectureは、アプリケヌションを構築するためのかなり単玔な䞀連の掚奚事項です。 しかし、私ず私の同僚である匷力な開発者の倚くは、このアヌキテクチャをすぐには理解したせんでした。 そしお最近、チャットルヌムやむンタヌネットで、それに関連する誀解が増えおいたす。 この蚘事で、私はコミュニティがClean Architectureをよりよく理解し、よくある誀解を取り陀くのを助けたいです 。


すぐに予玄したいのですが、劄想は私的な問題です。 誰もが誀解される暩利を持っおいたす。 そしお、それが圌に合っおいれば、私は邪魔したくありたせん。 しかし、他の人の意芋を聞くこずは垞に良いこずであり、倚くの堎合、人々は最前線にいた人の意芋さえも知りたせん。


起源


2011幎に、 ロバヌトC.マヌティンは 、ボブおじさんずしおも知られ、 スクリヌミングアヌキテクチャに関する蚘事を公開したした。これは、アヌキテクチャが䜿甚するフレヌムワヌクではなく、アプリケヌション自䜓に぀いお「叫ぶ」べきだず述べおいたす。 埌に、ボブおじさんが玔粋な建築のアむデアず戊う蚘事が出たした。 そしお2012幎に、圌はこのアプロヌチの䞻芁な説明である蚘事「 クリヌンアヌキテクチャ 」を公開したした。 これらの蚘事に加えお、ボブおじさんのビデオプレれンテヌションを芋るこずも匷くお勧めしたす。


Clean Architectureに関しお開発者の頭に最初に浮かんだ蚘事の元の抂芁は次のずおりです。


元の回路


Androidコミュニティでは、「 Androidを蚭蚈する...クリヌンな方法」ずいう蚘事の埌、Cleanはすぐに人気を博し始めたした。 フェルナンド・セハスによっお曞かれたした。 私は最初にクリヌンアヌキテクチャに぀いお孊びたした。 そしおその埌、圌はオリゞナルを探しに行きたした。 この蚘事では、Fernandoがこのレむダヌスキヌムを提䟛しおいたす。


フェルナンド・セハスのスキヌム


他のレむダヌがこの図にあり、他のいく぀かのむンタラクタヌず境界がドメむンレむダヌにあるずいう事実は、玛らわしいです。 元の写真は誰にずっおも明確ではありたせん。 蚘事では、倚くは曖昧たたはわずかに抜象的です。 そしお、誰もがビデオを芋るわけではありたせん通垞、英語の知識が䞍十分なため。 そしお今、 誀解のために、人々は䜕かを発明し始め、物事を耇雑にし、間違いを犯し始めたす...


それを理解したしょう


きれいな建築


クリヌンアヌキテクチャは、他のいく぀かのアヌキテクチャアプロヌチのアむデアを組み合わせたものです。



これは、䟝存関係ルヌル䟝存関係ルヌルを階局化しお埓うこずによっお実珟されたす。


䟝存関係ルヌル


䟝存性ルヌルは、内偎の局が倖偎の局に䟝存しおはならないこずを瀺しおいたす 。 ぀たり、ビゞネスロゞックずアプリケヌションロゞックは、プレれンタヌ、UI、デヌタベヌスなどに䟝存すべきではありたせん。 元の図では、この芏則は内偎を指す矢印で衚されおいたす。


蚘事によるず、倖偎の局で宣蚀された゚ンティティクラス、関数、倉数、その他の名前は、内偎の局のコヌドには衚瀺されたせん 。


このルヌルを䜿甚するず、倖偎のレむダヌの倉曎が内偎のレむダヌに圱響を䞎えないため、メンテナンスが容易なシステムを構築できたす。


レむダヌ


ボブおじさんは4぀のレむダヌを遞択したす。



この蚘事の䞭で、これらのレむダヌがどのようなものであるかをさらに詳しく怜蚎したす。 それたでの間、それらの間のデヌタの転送に぀いお説明したしょう。


遷移


レむダヌ間の遷移は、Boundariesを介しお 、぀たり、リク゚スト甚ずレスポンス甚の2぀のむンタヌフェヌスを介しお行われたす。 元の図Input / OutputPortの右偎に衚瀺されたす。 これらは、内偎の局が倖偎に䟝存しないようにするために必芁です䟝存性ルヌルに埓っおが、同時にデヌタを枡すこずができたす。


元の回路䞊のデヌタの流れ


䞡方のむンタヌフェむスは、内偎のレむダヌに属したす画像内の色に泚意しおください。


芋おください、コントロヌラヌはInputPortでメ゜ッドを呌び出し、UseCaseを実装し、次にUseCaseがPresenterを実装するOutputPortむンタヌフェヌスに応答したす。 ぀たり、デヌタはレむダヌ間の境界を越えたしたが、すべおの䟝存関係はUseCaseレむダヌを内偎に向けおいたす。


䟝存関係がデヌタフロヌずは反察の方向に向けられるように、 䟝存関係の反転の原理が適甚されたす 略語SOLIDの文字D。 ぀たり、UseCaseをプレれンタヌに盎接䟝存する䟝存芏則に違反する代わりに、レむダヌのむンタヌフェむスに䟝存するため、Presenterはこのむンタヌフェむスを実装する必芁がありたす。


UsingCaseがGateway / Repositoryにアクセスする堎合など、たったく同じスキヌムが他の堎所でも機胜したす。 リポゞトリに䟝存しないように、むンタヌフェヌスが匷調衚瀺され、UseCasesレむダヌに配眮されたす。


囜境を越えるデヌタに関しおは、 単玔な構造であるべきです。 DTOずしお枡すか、HashMapにラップするか、メ゜ッドを呌び出すずきに匕数ずしお枡すこずができたす。 しかし、それらは内局にずっおより䟿利な圢匏でなければなりたせん 内局にあるため 。


モバむルアプリの機胜


Clean Architectureは、わずかに異なるタむプのアプリケヌションを念頭に眮いお考案されたこずに泚意する必芁がありたす 。 倧䌁業向けの倧芏暡サヌバヌアプリケヌションであり、さらなる開発を必芁ずしない䞭皋床の耇雑さのモバむルクラむアントサヌバヌアプリケヌションではありたせんもちろん、さたざたなアプリケヌションがありたすが、ほずんどがそのようなものであるこずを認める必芁がありたす。 これを理解しないず、 過剰な゚ンゞニアリングに぀ながる可胜性がありたす。


元の図には、コントロヌラヌずいう単語がありたす。 これは、特にRuby On Railsのフロント゚ンドのために図に珟れたした。 倚くの堎合、リク゚ストを凊理しお結果を返すControllerず、この結果をビュヌに衚瀺するPresenterを分離しおいたす。 倚くの人はすぐには掚枬したせんが、Androidアプリケヌションではコントロヌラヌは必芁ありたせん 。


ボブおじさんはたた、蚘事で4局ある必芁はないず蚀っおいたす 。 任意の数を指定できたすが、䟝存関係ルヌルを垞に適甚する必芁がありたす。


Fernando Cejasの蚘事のスキヌムを芋るず、著者はこの機䌚を利甚しおレむダヌの数を3぀に枛らしたず思うかもしれたせん。 しかし、これはそうではありたせん。 芋おみるず、ドメむンレむダヌにはむンタラクタヌこれはUseCasesの別名ず゚ンティティの䞡方がありたす。


フェルナンドの蚘事に感謝したす。これはAndroidコミュニティでのCleanの開発に倧きな匟みを぀けたしたが、圌のスキヌムも混乱を招きたした。


誀解レむダヌず盎線性


ボブおじさんの元のサヌキットずフェルナンド・セハスのスキヌムを比范するず、倚くの人が混乱し始めたす。 線圢スキヌムは簡単に認識され、人々はオリゞナルを誀解し始めたす。 そしお、オリゞナルを理解しおいないので、圌らは誀解しお線圢になり始めたす。 円の䞭の碑文の䜍眮は神聖な意味を持っおいる、たたはコントロヌラヌを䜿甚する必芁がある、たたは2぀のスキヌムのレむダヌの名前を盞関させる必芁があるず誰かが考えおいたす。 おかしくお悲しいですが、基本的なスキヌムが゚ラヌの䞻な原因になっおいたす


修正を詊みたす。 はじめに、メむン回路をクリアしお、䞍芁なものを削陀したす。 そしお、ゲヌトりェむの名前をリポゞトリに倉曎したす。 これは、この゚ンティティのより䞀般的な名前です。


簡玠化された元のレむアりト


少し明確になりたした。 次に、これを行いたす。 レむダヌを断片にカットし、このスキヌムをブロックスキヌムに倉曎したす。ここで、色はレむダヌが属するこずを瀺したす。


円をブロックに倉える


䞊で蚀ったように、色はレむダヌを瀺したす。 たた、䞋の矢印は、䟝存関係ルヌルを瀺しおいたす。


結果の図では、UIからデヌタベヌスたたはサヌバヌぞ、たたはその逆ぞのデヌタの流れを簡単に想像できたす。 しかし、レむダヌをカテゎリに配眮するこずにより、線圢性に向けお別のステップを螏みたしょう。


カテゎリヌ別のレむダヌ

フェルナンド・セハスずは異なり、私は意図的にこの分離をレむダヌで呌ぶこずはしたせん。 すでにレむダヌを分割しおいるからです。 カテゎリたたはパヌツず呌びたす。 奜きな名前を付けるこずができたすが、「レむダヌ」ずいう蚀葉を再利甚しないでください。


それでは、フェルナンドサヌキットで䜕が起こったのかを比范したしょう。


フェルナンドセハスサヌキットずの比范

私は今、すべおが適所に萜ち始めたこずを願っおいたす。 私の意芋では、フェルナンドにはただ4぀の局があるず䞊蚘で述べたした。 今ではそれも明らかになったず思いたす。 ドメむン郚分には、ナヌスケヌスず゚ンティティの䞡方がありたす。


このようなスキヌムは簡単に認識されたす。 結局のずころ、通垞、アプリケヌションのむベントずデヌタはUIからバック゚ンドたたはデヌタベヌスに、たたはその逆に移動したす。 このプロセスを説明したしょう


UIからのデヌタストリヌム

赀い矢印はデヌタの流れを瀺したす 。


ナヌザヌむベントはプレれンタヌに送られ、プレれンタヌはナヌスケヌスに枡されたす。 ナヌスケヌスはリポゞトリにリク゚ストを行いたす。 リポゞトリはどこかでデヌタを取埗し、゚ンティティを䜜成しおUseCaseに枡したす。 したがっお、ナヌスケヌスは必芁なすべおの゚ンティティを取埗したす。 次に、それらずそのロゞックを適甚するず、Presenterに返される結果を受け取りたす。 次に、結果がUIに衚瀺されたす。


レむダヌ間の遷移カテゎリではなく、異なる色でマヌクされたレむダヌでは、前述の境界が䜿甚されたす。


2぀のスキヌムがどのように関連するかを理解したので、次の誀解を芋おみたしょう。


誀解゚ンティティではなくレむダヌ


タむトルからわかるように、誰かが゚ンティティがダむアグラムに衚されおいるず考えおいたすこれは特にUseCasesずEntitiesに圱響したす。 しかし、これはそうではありたせん。


ダむアグラムにはレむダヌが描かれおおり、倚くの゚ンティティを含めるこずができたす 。 これらには、レむダヌ間の遷移境界、さたざたなDTO、レむダヌのメむンクラスUseCasesレむダヌのむンタラクタヌなどのむンタヌフェむスが含たれたす。


ボブおじさんのスピヌチのビデオに瀺されおいるパヌツから組み立おられた図を芋るのは䞍必芁ではありたせん。 クラスず䟝存関係を瀺したす 


ボブおじさんによるパフォヌマンスのクラス図


二重線を参照しおください これらは、レむダヌ間の境界です。 ビデオでは、すべおのロゞックアプリケヌションおよびビゞネスが倖界から隔離されおいるずいう事実に䞻県が眮かれおいたため、゚ンティティレむダヌずナヌスケヌスレむダヌの分離は瀺されおいたせん。


私たちはすでに境界に粟通しおおり、ゲヌトりェむのむンタヌフェヌスは同じです。 Request / ResponseModelは、レむダヌ間でデヌタを転送するための単なるDTOです。 䟝存関係のルヌルによれば、それらは写真に芋られる内偎の局にあるはずです。


コントロヌラヌに぀いおも話したしたが、興味はありたせん。 その機胜はPresenterによっお実行されたす。


たた、図のViewModelはMVVMのViewModelではなく、 アヌキテクチャコンポヌネントの ViewModelでもありたせん。 これは、Viewデヌタを送信するための単なるDTOであるため、Viewはダムであり、フィヌルドを単にメッシュしたす。 ただし、これらは実装の詳现であり、プレれンテヌションパタヌンの遞択ず個人的なアプロヌチに䟝存したす。


UseCasesレむダヌには、むンタヌアクタヌだけでなく、プレれンタヌず連携するための境界、リポゞトリず連携するためのむンタヌフェむス、および芁求ず応答のためのDTOも含たれおいたす。 これから、オリゞナルのスキヌムがただ局を反映しおいるず結論できたす。


誀解゚ンティティ


゚ンティティは、誀解によっお正圓に最初の堎所を取りたす。


それだけでなく、ほずんど誰も最近たで私を含めおそれが䜕であるかを理解しおいないだけでなく、圌らはDTOず混同されおいたす。


チャットに参加した埌、玛争が発生したした。そこでは、゚ンティティはデヌタレむダヌでJSONを解析した埌に取埗されたオブゞェクトであり、DTOはInteractorsが操䜜するオブゞェクトであるこずが蚌明されたした...

他の人がそのような゚ラヌを起こさないように、うたく理解しようずしたす。


゚ンティティずは䜕ですか


ほずんどの堎合、むンタヌアクタヌが機胜するPOJOクラスずしお認識されたす。 しかし、これはそうではありたせん。 少なくずもそうではありたせん。


蚘事の䞭で、ボブおじさんは、 ゚ンティティはビゞネスのロゞック 、 ぀たり特定のアプリケヌションに䟝存しないが、倚くの人に共通するすべおのものを カプセル化するず述べおいたす 。 ただし、別のアプリケヌションがあり、既存のビゞネス向けに調敎されおいない堎合、゚ンティティは、最も䞀般的で高レベルのルヌルを含むアプリケヌションのビゞネスオブゞェクトになりたす 。


「゚ンティティはビゞネスオブゞェクトです」ずいうフレヌズが最も玛らわしいず思いたす。 さらに、䞊の図では、Interactorはビデオからゲヌトりェむから゚ンティティを取埗したす。 たた、これらは単なるPOJOオブゞェクトであるずいう感芚を匷化したす。


しかし、この蚘事では、 Entityはメ゜ッドたたは構造ず機胜のセットを持぀オブゞェクトになり埗るずも述べおいたす 。 ぀たり、デヌタではなくメ゜ッドが重芁であるずいう事実に重点が眮かれおいたす。


これは、最近芋぀けたボブおじさんの説明でも確認されおいたす。
ボブおじさんは、゚ンティティにはアプリケヌションに䟝存しないビゞネスルヌルが含たれおいるず蚀っおいたす。 そしお、それらは単なるデヌタオブゞェクトではありたせん。 ゚ンティティには、デヌタを持぀オブゞェクトぞの参照が含たれる堎合がありたすが、その䞻な目的は、さたざたなアプリケヌションで䜿甚できるビゞネスロゞックメ゜ッドを実装するこずです 。


そしお、ゲヌトりェむが写真の゚ンティティを返すずいう事実に぀いお、圌は次のように説明しおいたす。
ゲヌトりェむの実装は、デヌタベヌスからデヌタを受け取り、それを䜿甚しお、ゲヌトりェむが返す゚ンティティに枡されるデヌタ構造を䜜成したす。 実装されたこれは構​​図かもしれたせん


class MyEntity { private MyDataStructure data;}


class MyEntity extends MyDataStructure {...} 

, :


And remember, we are all pirates by nature; and the rules I'm talking about here are really more like guidelines

( : , , , , 
)

, , . - , .


, Entities :



, , Entities UseCases, .


: UseCase / Interactor


UseCase Interactor. : « Interactor ». : « Interactor’e UseCase?».


Interactor’a , . :


«...interactor object that implements the use case by invoking business objects.»


:


Interactor – , use case ( ), - (Entities).


Use Case ?
Uncle Bob «Object-Oriented Software Engineering: A Use Case Driven Approach», Ivar Jacobson 1992 , , Use Case.


Use case – , , .


, :


Use Case

Use Case , .


, , . .


– Use Case’a, – .


:



Ivar Jacobson Use Case , ControlObject.
Uncle Bob , , Controller MVC Interactor. , UseCase.
.


, Interactor use case execute() , . .


.


- , Interactor’a – . . .


Interactor’ , use case’.
, , . Interactor’, .


: « – UseCase’», – . . , UseCase Interactor , .


Interactor UseCase, : Interactor/UseCase – , use case ( ).


, , -, , – Repository.



- , . Uncle Bob Gateway, Repository.


Repository


Repository? , , ( Fernando Cejas ), .


Repository - . , , .


Android- Repository , .


Hannes Dorfmann’.


Gateway


Repository, «» , login() (, Repository, – , ).


, Gateway – , . Gateway , API . , , .


«», .


Repository/Gateway Interactor?


, . !
Repository Interactor.


, , , Repository Presenter’a, Interactor.


Repository , Dependency Rule Repository . – Interactor . Interactor, , , proxy-interactor’, , .


, , Interactor, , , Interactor , . .


:


, . .


DTO Entities . , . Dependency Rule .


– . .


DTO :



DTO Enitities:



.


:


, / , ( ). , API . , , .


: Interactor’e


, . , c:
So when we pass data across a boundary, it is always in the form that is most convenient for the inner circle.
( , )


Interactor .
Interface Adapters, Presenter Repository.


?


. API . , login() Profile OrderState. , , Repository.


LoginResponse Profile OrderState , Interactor’e Repository?


Interactor’e. , .. .


Repository. :



Interactor, , .


Interactor Repository?


Interactor Repository. , « Repository/Gateway Interactor?».


Clean Architecture .
:



, , . , . .


RxJava Clean Architecture


Android- RxJava. , Fernando Cejas , RxJava Clean Architecture.


, , , , Boundaries ( Dependency Rule) Observable Subscriber.


, RxJava , . , – Clean Architecture.


, RxJava . Java 9 util.concurrent.Flow, Reactive Streams, RxJava2. - RxJava, .


: Clean Architecture MVP?


, ? .
:



: Clean Architecture


. Google Architecture Components.


- . . .


, – . , , , . , .


, , .


!


. . Clean Architecture, , , « »!



Source: https://habr.com/ru/post/J335382/


All Articles