私はクリーンなアーキテクチャについて学んでいるだけで、すぐに構築したいアプリケーションの概念実証を設計しようとしています。
クリーンアーキテクチャでは、プレゼンテーション層とドメインモデル層がアプリケーション層によって分離されています。これが、WebベースのMVCアプリケーションや、ほとんどの操作がCRUDである「レコードベースの」デスクトップアプリケーションなどのステートレスアプリケーションにとってどのように意味があるかを理解しています。また、私の理解では、プレゼンテーション層はドメインオブジェクトを直接使用するのではなく、アプリケーション層のモデルとの間でマップされる独自のViewModelを持つ必要があります。この仮定は正しいですか?
私が開発する予定のアプリケーションは、ユーザーが一度に1つの動きでチェスのゲームを入力できるようにします。チェスのルールはドメインモデルレイヤーにあるように思えます。この場合、プレゼンテーション層は各ユーザー入力をどのように検証しますか(各ムーブの合法性を検証するため)?毎回アプリケーション層を通過する必要がありますか、それともプレゼンテーション層にドメインオブジェクトを直接操作させて、ユーザー入力に従ってモデルを構築し、保存するときにアプリケーション層に送信する方が理にかなっていますか。データベースに?
これについて説明するリソースをオンラインで見つけようとしましたが、すべての例/コース/チュートリアルで、Webアプリケーションまたは少なくともデータを保存する前にビジネスルールが適用されるCRUDタイプのステートレスアプリケーションについて話していることがわかりました。それらをロードした後。私のアプリケーションでは、ユーザーがViewModelを編集して即座にフィードバックを与えるたびに、チェスのルールを適用する必要があります。
(私が書いたように、ラバーダック効果が発生し、私はおそらくアプリケーション層を常に通過する必要があると思います。もっと経験豊富な人々がどう思うかを知りたいです)
約1年前から、リッチデスクトップアプリケーションにClean Architectureを使用していますが、GUIを多用したイベントベースのアプリケーションに適しています。ジャンプアンドランのような「リアルタイム」ゲームには適していませんが、チェスゲームは問題なく動作します。
あなたの質問を解体する代わりに、私はレイヤーの要約を通り、そして置物を動かすプロセスに従うことで終わります。
"企業全体のビジネスルール"。あなたの場合、それはゲームのルールをカプセル化することを意味します。実際のビジネスの代わりに古くからあるチェスのゲームをここに置くと、利点が得られます。このレイヤーを作成した後、ここでバグを発見した場合にのみ、変更が必要になります。
ユースケースは、アプリケーションのユーザーアクションと考えてください。この層では、これらのユーザーアクション、ユーザーが行う入力、ユーザーが返す出力、およびユーザーが目標を達成するために使用するインターフェイスを定義します。このようなユースケースでは、実際にはそれ自体は何も行いません。何が起こるかを段階的に説明するようなものです。
「面倒な作業」を行うコードをここに記述します。
このレイヤーは、純粋に外部の要素からコード(=内側の3つのレイヤー)へのアダプターです。ほぼ完全にラッパーで構成されています。この部分は、他の3つのレイヤーについて知るために、必要にならないように非常に薄く/単純である必要があります。それはあなたのモデルを知りません、それは文字列、int、イベントなどでのみ機能します。
これの例外は、すべてを接続するセットアップコードである可能性があります。これは、意味的というよりも実際的な理由でこのレイヤーにもあります。
(これを「プレゼンテーションレイヤー」と呼んでいましたが、少し誤解を招くかもしれません。一方で、DB、一部のハードウェアデバイス、インターネットアクセスなども、このレイヤーでラッパーを取得するすべての外部のものであるためです。他方、すべての「ロジックの表示」-モデルをGUIの文字列に変換するような-は前のレイヤーで発生します。)
BoardView
ですBoardView
は、単純な情報_('A', 1, 'B', 3)
_でBoardViewPresenter
を呼び出しますBoardViewPresenter
は、エンティティレイヤーから適切なモデルに変換します。ChessPiece
とBoardPosition
B3を見つけます。MoveChessPieceRequest
に入れます。MoveChessPieceUseCase
に送信します(明らかにユースケースレイヤーからも)。MoveChessPieceUseCase
は、エンティティレイヤーのルールに従ってリクエストを検証します。MoveChessPieceResult
をfalseに設定してSucceeded
を早期に返します。BoardViewPresenter
にMoveChessPieceResult
が追加され、肯定的な結果に反応します。ChessPieceView
を取得し、Move('B', 3)
に通知します。ChessPieceView
は、画面上の実際の位置を変更します。ViewModelアーキテクチャ および
クリーンアーキテクチャ は同じではありません。
いくつかの点で互換性がありません。不用意に混ぜないでください。
それらを分ける一番のことは cycles です。 ViewModelアーキテクチャは、設計にサイクルを作成するのに適しています。クリーン(またはタマネギ、または16進数)アーキテクチャはそうではありません。 ViewModelはバインダーを使用して、これが引き起こす問題を解決します。 Cleanは、 依存関係の逆転の原則 に従い、外部レイヤーをスワップ可能なプラグインにし、自分でバインドすることを期待しています。
続けますが、これについては話しました before 。ここからは、ViewModelが私たちが無視できる迷ったアイデアであると仮定します。
クリーンアーキテクチャでは、プレゼンテーション層とドメインモデル層がアプリケーション層によって分離されています。これが、WebベースのMVCアプリケーションや、ほとんどの操作がCRUDである「レコードベースの」デスクトップアプリケーションなどのステートレスアプリケーションにとってどのように意味があるかを理解しています。また、私の理解では、プレゼンテーション層はドメインオブジェクトを直接使用するのではなく、アプリケーション層のモデルとの間でマップされる独自のViewModelを持つ必要があります。この仮定は正しいですか?
これらの他の用語の多くは、クリーンアーキテクチャに由来するものでもありません。それらは Onion Architecture からのものです。
ボブおじさんがClean Architectureを明確にその概念と構造の多くをOnion Architectureから持ち上げたので( Hex/Ports and Adapters から同じことをするので)、ここで私はずっと混乱を気にしません。ブログや本にあなたを駆り立てる、さまざまな話題の言葉を使っても、ほとんど同じ考えです。
あなたが言っていたように:
プレゼンテーション層とドメインモデル層は、アプリケーション層によって分離されています。
はい、「ドメイン」とはClean Architectureのエンティティを意味し、「アプリケーション層」とはCleanのアプリケーションビジネスルール(ユースケース)を意味します OSIsアプリケーション層 ではなく。
OnionsドメインをCleans EntitiesとUse Caseの両方にマッピングする人がいることに注意してください。それは、分離ロジックがまだ良い考えではないという意味ではありません。ここでは文字通りセマンティクスを議論しています。
だから私はあなたの仮定が正しいと思います。私があなたの意味を正しく解読しているなら。
私が開発する予定のアプリケーションは、ユーザーが一度に1つの動きでチェスのゲームを入力できるようにします。チェスのルールはドメインモデルレイヤーにあるように思えます。
私はそれに同意することができます。
...プレゼンテーション層はどのようにして各ユーザー入力を検証しますか(各ムーブの合法性を検証するため)?毎回アプリケーション層を通過する必要がありますか、それともプレゼンテーション層にドメインオブジェクトを直接操作させて、ユーザー入力に従ってモデルを構築し、保存するときにアプリケーション層に送信する方が理にかなっていますか。データベースに?
多くの場合、検証は1か所で行われるように見えますが、これがうまく機能することはめったにありません。その理由は、あるオブジェクトに有効なものは別のオブジェクトには無効なためです。各オブジェクトは、それ自体の専門家になることを目的としています。アプリケーション全体を考慮しなければならない1つの場所で発生するように強制することもできますが、これを考慮してください。ボードはそれがどれほど大きいかを認識しています。それをチェスに使用していることはわかりません。ボードがチェスが安全を保つと想定する場合、またはボードが大声で「私は8 x 8のボードです。このクレイジーな9,9ムーブをどこに置くかわからない」と言うべきですか。そのようにボードを設計すれば、そのコードを使用してチェッカーや三目並べをプレイしたり、ボードにそれらのゲームについて何も教えることなく行ったりできます。
ボードにボードの問題を検証させ、ゲームにゲームの問題を検証させることをお勧めします。そして、「ドメイン」のこれらの部分の両方を検討します。
これについて説明するリソースをオンラインで見つけようとしましたが、すべての例/コース/チュートリアルで、Webアプリケーションまたは少なくともデータを保存する前にビジネスルールが適用されるCRUDタイプのステートレスアプリケーションについて話していることがわかりました。それらをロードした後。私のアプリケーションでは、ユーザーがViewModelを編集して即座にフィードバックを与えるたびに、チェスのルールを適用する必要があります。
IOが遅い。スピードチェスはそれほど得意ではないかもしれませんが、IOに直接動きを送るという考えはまだ好きではありません。移動は最初にメモリに移動する必要があります。しかし、それらが検証された後にのみ。
ここで理解しておくべきことの1つは、例外を設けて検証を強制する必要がないことです。すべての移動は、状態を変更する試みです。すべての移動が状態の変化をもたらす必要はありません。移動するたびに、ユーザーはフィードバックを受け取る必要があります。検証オブジェクトが何らかの方法でフィードバックを提供できる限り、状態を変更する試みをシャットダウンしても問題ありません。
これで出力ポートが表示されます。 Clean Architectureプラグインの気の利いた点の1つは、ソースコードの変更がコードベースを介して伝播されないようにするすべてが循環的であるにもかかわらず、制御フローをどこにでも送信できることです。
Presenterとユースケース出力ポートの間の開いた矢印は、ある種の多態性を求めています。情報を必要な場所に流すことができ、アーキテクチャが循環しないことを保証できる限り、.
(私が書いたように、ラバーダック効果が発生したので、おそらくアプリケーション層を常に通過する必要があると思います。経験豊富な人々の考えを知りたいです)
確かに、それがバリデーターが住んでいる唯一の場所である限り。それは私がそれらを置く場所です。
Clean ArchitectureとChessについて詳しくお話ししますが、それについてもお話ししました before 。
実際、私はこれについて話しました たくさん 。
それは素晴らしい質問だと私は考えてきました。私が取っているアプローチは次のとおりです。
Board
とPiece
オブジェクトのセットがあります。 Piece
オブジェクトには、一般的な部分から継承する具体的なクラス(例:Rook
、Queen
、Pawn
など)があります(たとえば、すべての部分がボードですが、ピースに固有です)。単体テストを作成して、ドメインロジックを検証します。クリーンアーキテクチャは、アプリケーションを構築するための他の多くのアーキテクチャパターンと同様に、どのロジックがどこに行くかを体系化する手段にすぎないことを覚えておいてください。彼ら一人一人が彼らが対処しようとしている特定の目標と課題を持っています。
クリーンアーキテクチャに関する記述では、onlyを自分のすぐ下のレイヤーで操作する必要があります。作業中のレイヤーよりも下位のレイヤーを操作できます。それはどういう意味ですか?
仕立て屋がファッションデザイナーに成長する方法と同様に、これらのパターンを書いたとおりに完全に使用する必要はありません。あなたはあなたがあなたのビジョンのためによりよく働く何かを思いつくためにあなたがあなたがあなたがあなたがあなたがあなたのビジョンのためにより良いものを思いつくために2、3の異なるパターンの間で少しミックスしてマッチすることができるのを見つけるでしょう。これらのパターンは常にインスピレーションを得て、そこから作業の基本的な構造を提供するために存在します。