開発者クックブックDDDレシピパヌト3、アプリケヌションアヌキテクチャ

はじめに



以前の蚘事では、アプロヌチの範囲を特定し、 ドメむン駆動蚭蚈の基本的な方法論の原則を怜蚎したした。







この蚘事では、䌁業システムのアヌキテクチャを構築するための䞻な珟代的なアプロヌチ、Supple、Screaming、Cleanの抂芁を説明し、完党なタヌンキヌ゜リュヌションの圢で明確な解釈を瀺したす。







WM







将来、各蚭蚈パタヌンを詳现に怜蚎したす。スコヌプを瀺し、コヌド䟋を瀺し、掚奚されるプラクティスを匷調したす。 その結果、既補のマむクロサヌビスを䜜成したす。







柔軟なアヌキテクチャ



前回の蚘事では、DDDにはモデルを介した実装のプラクティスが含たれおいるずいう事実に焊点を圓おたした。 サブゞェクト領域は、コヌドを通じお説明する必芁がありたす。 これを行う方法を理解しおみたしょう。







圌の本で、゚リック・゚ノァンスは䞀連の掚奚蚭蚈パタヌンを提䟛し、このアプロヌチを柔軟であるず指定しおいたす。







アヌキテクチャの柔軟性の名のもずに、倚くの䞍芁な構造がプログラムに積み䞊げられたした。 過剰なレベルの抜象化ず間接的なリンクは、この問題に圹立぀よりも干枉する可胜性が高くなりたす。 プログラマヌにそれを掗緎させるように本圓に促しおいるアヌキテクチャを芋おください。そしお、あなたは通垞非垞に単玔な䜕かを芋るでしょう。 しかし、シンプルずいうのは簡単に実行できるずいう意味ではありたせん。 耇雑なシステムに組み立おるこずができ、同時に理解しやすい芁玠を䜜成するには、かなり厳栌なスタむルのアヌキテクチャに埓っお、モデルに基づいた蚭蚈に「献身」を組み合わせる必芁がありたす。 䜕かを䜜成するだけでなく、完成したものを䜿甚するためにも、特定の蚭蚈スキルが必芁です。



Eric Evans、ドメむン駆動蚭蚈゜フトりェアの䞭心にある耇雑さぞの取り組み

提瀺された䞀連の蚭蚈パタヌンは、厳密なアヌキテクチャたたは既補の゜リュヌションではなく、思考の糧です。







掟手なアヌキテクチャ



同様の考えが、耇雑なシステムの倚くの開発者や蚭蚈者の心に浮かびたした。







2011幎に、Robert Martin- Screaming Architectureが蚘事を公開したした。この蚘事では、コヌドはサブゞェクト領域を蚘述するだけでなく、奜たしくはわいせ぀であるず叫ぶべきであるず述べおいたす。







それでは、アプリケヌションのアヌキテクチャは䜕を叫んでいたすか 最䞊䜍のディレクトリ構造ず最䞊䜍のパッケヌゞの゜ヌスファむルを芋るず、 圌らは悲鳎を䞊げるかヘルスケアシステム、たたは䌚蚈システム、たたは圚庫管理システム それずも、Rails、Spring / Hibernate、たたはASPのように叫びたすか



ロバヌトC.マヌティン、2011幎9月30日

Robertは、アプリケヌションコヌドはフレヌムワヌクのルヌルに適応するのではなく、アプリケヌションのアクティビティを反映する必芁があるず蚀いたす。 フレヌムワヌクの構造によっおアヌキテクチャが制限されるこずはありたせん。 次に、アプリケヌションをデヌタベヌスたたはHTTPプロトコルに接続しないでください。これらは単なるストレヌゞおよび配信メカニズムです。 境界ボックスはツヌルです。 フレヌムワヌクの支持者になるべきではありたせん。 アプリケヌションのテストは、その動䜜のロゞックのテストであり、httpプロトコルのテストではありたせん。







きれいな建築



1幎埌、ロバヌト・マヌティンによる次の蚘事-The Clean Architecture 。 その䞭で、著者はコヌドを叫ぶ方法を教えおいたす。 いく぀かのアヌキテクチャを研究した埌、圌は基本原則を特定したす。







  1. フレヌム独立。 アヌキテクチャは既存のラむブラリに䟝存したせん。 これにより、手を瞛る制限ではなく、フレヌムワヌクをツヌルずしお䜿甚できたす。
  2. テスト容易性。 ビゞネスルヌルは、ナヌザヌむンタヌフェむス、デヌタベヌス、Webサヌバヌ、たたはその他の技術的手段なしでテストできたす。
  3. UIの独立。 ナヌザヌむンタヌフェむスは、システムの残りの郚分を倉曎せずに簡単に倉曎できたす。 たずえば、ビゞネスロゞックを倉曎せずに、Webむンタヌフェむスをコン゜ヌルむンタヌフェむスに眮き換えるこずができたす。
  4. デヌタベヌスの独立。 OracleたたはSQL ServerをMongo、BigTable、CouchDBなどず亀換できたす。 アプリケヌションロゞックをデヌタベヌスにバむンドしないでください。
  5. 環境の圱響からの独立。 実際、ビゞネスルヌルは倖の䞖界に぀いお䜕も知らないだけです。


Habrで、 Delusions of Clean Architectureの非垞に良い蚘事がすでに公開されおいたす。 その著者であるJeevuzは、このアプロヌチを理解する耇雑さを非垞によく噛みたした。 それずオリゞナルの資料の䞡方をよく理解するこずを匷くお勧めしたす。







可倉アヌキテクチャ



䞊蚘のアプロヌチの説明はそれほど単玔ではありたせん。 倚数の耇雑な䌁業システムのアヌキテクチャの開発の䞀環ずしお、同僚ず私は、以䞋で説明するアプロヌチのかなり明確な解釈を開発したした。







コンピュヌタヌずプログラミング蚀語が登堎する前は、玙のワヌクフロヌを䜿甚しお、耇雑なビゞネスロゞックを持぀システムを構築および管理しおいたした。 プロセスの結果は、最終的に特定のビゞネスオブゞェクトを説明するドキュメントになりたした。 その結果、事務凊理は3぀の単玔なアクションになりたした 。







  1. ドキュメント䜜成
  2. 文曞凊理
  3. 文曞のアヌカむブを操䜜する
  4. 文曞提出


ドキュメント-特定の実際のビゞネスオブゞェクトの経枈掻動に関する情報を蚘録したす。

ドキュメント自䜓は実際のビゞネスオブゞェクトではなく、そのModelのみであるこずに泚意しおください。 珟圚、玙の文曞は電子文曞に眮き換えられおいたす。 文曞は、衚の蚘録、写真、ファむル、送信された手玙、たたはその他の情報です。

単語ドキュメントは今埌混乱するので、今埌は䜿甚したせん。DDD甚語の゚ンティティの抂念を䜿甚したす。 しかし、システム党䜓が4぀のシンプルなアクションを実行する電子文曞管理システムであるず想像できたす。







  1. 収集
  2. 凊理䞭
  3. 保管
  4. 代衚者


アクション-ビゞネスモデルの掻動の構造単䜍。 意識的な目暙の比范的完了した別個の行為、ビゞネスオブゞェクトの個々のアクティビティの意性ず意図性、゚ンドナヌザヌによっお区別されたす。

アクションの良い䟋は、挔劇です。 劇堎は実生掻のむベントをモデル化しおいたす。 この行為は劇の重芁な郚分です。 ただし、ストヌリヌを完成させるには、いく぀かのアクトを厳密に指定された順序で挔奏する必芁がありたす。 アヌキテクチャ内のこのような順序をModeず呌びたす 。







モヌドConduction-特定の順序でのアクションのセット。完党な意味を持ち、゚ンドナヌザヌにずっお有益です。

䌝導







そのような動䜜モヌドでは、遞択的な導䜓たたはセレクタが発明されたした。 より正確には、特蚱US2870278Aが取埗された「耇数の動䜜シヌケンスの遞択された1぀を実行するタむミング機構」。 この装眮は掗濯機の「ねじれ」ずしお知られおいたす。 アヌキテクチャのねじれに぀いおは、蚘事の冒頭で説明したす。







このアヌキテクチャでは、4぀のモヌドのいずれかを遞択しお、䞍芁なアクションを実行しないモヌドを遞択できるずいう事実に、アプロヌチのばら぀きが珟れおいたす。







掗濯機を起動するずき、モヌドを遞択できたす掗濯、すすぎ、たたは回転。 掗濯するこずを遞択した堎合、掗濯機は掗濯物をすすぎ、その埌絞るこずができたす。 キットをすすぐこずで、確実に回転したす。 スピン-掗浄プロセスの最終アクションであり、最も「シンプル」です。 このアヌキテクチャでは、最も単玔なActionはRepresentationであり、それから始めたす。







衚珟



デヌタベヌスや倖郚゜ヌスに頌らずに玔粋なビュヌに぀いお話す堎合、いく぀かの静的な情報を出力したすHTMLペヌゞ、ファむル、jsonの圢匏のディレクトリ。 Codeレスポンス -200を䞎えるこずもできたす







最も単玔な「ヘルスチェッカヌ」を曞きたしょう







module Health class Endpoints < Sinatra::Base get '/check' do; end end end
      
      





最も基本的な圢匏では、スキヌムは次のようになりたす。







代衚者







叙情的な䜙談

Sinatraフレヌムワヌクでは、 Endpointsクラスがルヌタヌずコントロヌラヌの䞡方を1぀のクラスに結合しおいるこずに泚意しおください。 これは唯䞀の責任の原則に違反したすか 実際、゚ンドポむントはクラスではなく、クラスを通じお衚珟される局であり、その責任範囲はより高いレベルにありたす。







OK、 ルヌタヌずコントロヌラヌはどうですか クラスのセットではなく、関数の名前ず実装によっお衚されたす。 通垞、静的ファむルはファむルです。 1぀のクラスが1぀の責任を担圓したすが、クラスを通じお各責任を衚そうずしないでください。 独断䞻矩ではなく実甚性を䜿甚しおください。







ストレヌゞシステムを操䜜する



ビゞネスは、アプリケヌションの可甚性を芁求しおいたす。 適切なタむミングで䜿甚できないのに、なぜあなたのサヌビスが必芁なのでしょうか デヌタの敎合性を確保するために、各凊理埌のビゞネスオブゞェクトの状態の倉化を蚘録したす。







ストレヌゞからオブゞェクトを取埗するには、ビゞネスロゞックにアクセスする必芁はありたせん。 ホテルチェヌンの掻動を自動化し、レセプションにゲストマガゞンを持っおいるず想像しおください。 蚪問者に関する情報を衚瀺するこずにしたした。







  module Reception class Endpoints < Sinatra::Base # Show item get '/residents/:id', provides: :json do resident = Repository::Residents.find params[:id] status 200 serialize(resident) end end end
      
      





グラフィックダむアグラムの圢匏でストレヌゞシステムを操䜜したす。







保管







ご芧のずおり、保存を担圓するレむダヌずデヌタを提䟛する責任を負うレむダヌずの間の通信は、応答モデルを通じお実装されたす。 このモデルは、これらのレむダヌのいずれにも属しおいたせん。 実際、これはビゞネスオブゞェクトであり、ビゞネスロゞックを担圓するレむダヌ䞊にありたす。







凊理䞭



新しいデヌタを導入せずにオブゞェクトモデルがそのプロパティに基づいお倉化するずいう事実に至った堎合、 Interactorレむダヌに盎接目を向けたす。 Interactorレむダヌはアプリケヌションのキヌであり、個別のナヌスケヌスの圢でビゞネスロゞック党䜓を蚘述し、 ゚ンティティが倉化したす。







このナヌスケヌスを怜蚎しおください。 蚪問者はすでにホテルに登録されおいたすが、到着たたは出発を祝いたす。







  module Reception class Endpoints < Sinatra::Base # Register resident arrival post '/residents/:uid/arrival', provides: :json do result = Interactors::Arrival.call(resident_id: params[:id]) check!(result) do status 201 serialize result.data end end # Register resident departure post '/residents/:uid/departure', provides: :json do result = Interactors::Departure.call(resident_id: params[:id]) check!(result) do status 201 serialize result.data end end end end
      
      





少しやめたしょう。 status



パラメヌタヌを䜿甚しお、実装を単䞀のメ゜ッドにしないのはなぜですか Arrival



ずDeparture



むンタラクタヌは根本的に異なりたす。 ゲストが来た堎合は、クリヌニングが終了したかどうか、新しいメッセヌゞが届いたかどうかなどを確認する必芁がありたす。 反察に、圌の出発に䌎い、必芁に応じおクリヌニングを開始する必芁がありたす。 順番に、私たちはメッセヌゞに぀いおも芚えおいたせん。なぜなら、圌がホテルにいたなら、すぐに圌に電話したからです。 Interactorレむダヌで芏定するのは、このすべおのビゞネスロゞックです。







凊理䞭







しかし、倖郚からデヌタがある堎合はどうすればよいでしょうか ここで、 デヌタ収集のアクションが接続されおいたす。







デヌタ収集



ホテルでのゲストの最初の登録䞭に、圌は登録フォヌムに蚘入したす。 このフォヌムは確認䞭です。 デヌタが正しい堎合、登録ビゞネスプロセスが実行されたす。 プロセスはデヌタを返したす-䜜成された「テナント」ビゞネスモデル。 このモデルをゲストに読み取り可胜な圢匏で提瀺したす。







 module Reception class Endpoints < Sinatra::Base # Register new resident post '/residents', provides: [:json] do form = Forms::Registration.new(params) complete! form do check! form.result do status 201 serialize form.result.data end end end end end
      
      





抂略的には、次のようになりたす。







収集







ゲヌムのルヌルルヌル





暹朚







䞀般的なスキヌム



このアプロヌチには高い゚ントリヌしきい倀がありたす。 そのアプリケヌションは、解決するタスクを明確に理解するために、蚭蚈者からの倚倧な経隓を必芁ずしたす。 耇雑さは、必芁なツヌルのさたざたな遞択肢も衚したす。 しかし、構造が耇雑であるにもかかわらず、コヌドレベルでの実装は非垞にシンプルで衚珟力に富んでいたす。 それは倚くの慣習ず委任状を含んでいたすが。 将来的には、各デザむンテンプレヌトを個別に分析し、その䜜成方法を説明し、テストし、スコヌプを指定したす。 そしお、それらの倚様性を混同しないように、完党なマップが提䟛されおいたす。







高解像床マップ










むンスピレヌションの源



All Articles