CQRSは過剰設計ではありませんか?


15

古き良き時代のリポジトリを今でも覚えています。しかし、リポジトリは時間とともにいものになりました。その後、CQRSが主流になりました。彼らは素晴らしく、新鮮な空気の息吹でした。しかし、最近、コントローラーのアクションメソッド(特にアクション自体が何らかのコマンド/クエリハンドラーであるWeb Api)でロジックを正しく維持しないように何度も自問しています。

以前は、そのための明確な答えがありました。すべてのそれらのモックできないシングルトンと全体的ないASP.NETインフラストラクチャでControllerをテストするのは難しいので、テストのためにそれをしました。しかし、時代は変わっており、ASP.NETインフラストラクチャクラスは、今日では(特にASP.NET Coreで)はるかに単体テストに適しています。

典型的なWebApi呼び出しは次のとおりです。コマンドが追加され、SignalRクライアントに通知されます。

public void AddClient(string clientName)
{
    using (var dataContext = new DataContext())
    {
        var client = new Client() { Name = clientName };

        dataContext.Clients.Add(client);

        dataContext.SaveChanges();

        GlobalHost.ConnectionManager.GetHubContext<ClientsHub>().ClientWasAdded(client);
    }
}

簡単に単体テスト/モックできます。さらに、OWINのおかげで、ローカルWebApiおよびSignalRサーバーをセットアップし、統合テストを実行できます(ちなみにかなり高速です)。

最近、面倒なコマンド/クエリハンドラを作成するモチベーションが低下し、Web Apiアクションにコードを保持する傾向がありました。ロジックが繰り返されるか、それが本当に複雑で、それを分離したい場合にのみ、例外を作成します。しかし、ここで正しいことをしているかどうかはわかりません。

典型的な最新のASP.NETアプリケーションでロジックを管理するための最も合理的なアプローチは何ですか?コードをコマンドおよびクエリハンドラーに移動するのが妥当なのはいつですか?より良いパターンはありますか?

更新。DDD-liteアプローチに関するこの記事を見つけました。したがって、コードの複雑な部分をコマンド/クエリハンドラに移動するという私のアプローチは、CQRS-liteと呼ばれるようです。


1
CQRSがどのように物事をテスト可能にするのか、シングルトン/コントローラ/などの助けにはなりません。それらはほとんど無関係です。また、(カウンター?)の例ではまだコマンドを作成していますが、これは奇妙です。
-guillaume31

インフラストラクチャコードを使用してコードを保持する(クライアントのIPアドレスを取得する)場合、テストするのは困難です。ロジックをクエリ/コマンドに分離すると、はるかに簡単になります。コードサンプルは少しわかりにくいので、更新しました。
SiberianGuy

1
クエリとコマンドにはロジックがありません。それらは愚かなDTOです。次に、コマンド/クエリハンドラがありますが、それらはアプリケーションサービス、インタラクター、ビジネスサービスとまったく同じで、CQRS以外のコンテキストで名前を付けます。コントローラーとは別のオブジェクトに適用/ユースケースロジックを配置することは、CQRS固有のものではありません。
guillaume31

また、シングルトンと注入された依存関係の問題は、CQRSに完全に直交しています。リポジトリシングルトンを呼び出すCommandHandlerシングルトンを呼び出すコントローラーを使用できます
...-guillaume31

1
@ guillaume31、CQRSはリポジトリ/アプリケーションサービス呼び出しよりも扱いにくい傾向があります。通常、2〜3個のクラス(クエリ、クエリハンドラ、クエリ結果)、インフラストラクチャなどが必要です。
SiberianGuy

回答:


17

CQRSは比較的複雑でコストのかかるパターンですか?はい。

それは過剰設計ですか?絶対違う。

Martin FowlerがCQRSについて語っている元の記事では、CQRSが適用できない場合にCQRSを使用しないことに関する多くの警告を見ることができます。

他のパターンと同様に、CQRSはある場所では便利ですが、他の場所では役に立ちません。

CQRSは関係者全員にとって大きな精神的飛躍であるため、利益にジャンプする価値がない限り、取り組むべきではありません

私はCQRSの成功した使用に出くわしましたが、これまで私が遭遇したケースの大部分はそれほど良くありませんでした ...

これらの利点にもかかわらず、CQRSの使用には非常に注意する必要があります

...そのようなシステムにCQRSを追加すると、かなり複雑になります。

上記の私の重点。

アプリケーションがすべてにCQRSを使用している場合、過剰に設計されているのはCQRSではなく、アプリケーションです。これは、いくつかの特定の問題、特に書き込みの同時実行が主要な懸念事項である高パフォーマンス/大容量アプリケーションを解決するための優れたパターンです。

また、アプリケーション全体ではなく、ごく一部にすぎない場合もあります。

私の仕事の実例として、注文入力システムでCQRSを使用しています。注文を失うことはできません。また、特定の時間に数千の注文が異なるソースから同時に発生するスパイクがあります。CQRSは、システムの稼働と応答性を維持するのに役立ちましたが、バックエンドシステムを適切に拡張して、必要に応じてこれらの注文をより速く処理し(バックエンドサーバーを増やす)、不要なときにより遅く/安くすることができました。

CQRSは、複数のアクターが同じデータセットで共同作業したり、同じリソースに書き込んだりする問題に最適です。

それ以外に、単一の問題を解決するために作成されたパターンをすべての問題に広めると、より多くの問題が発生します。


その他の便利なリンク:

http://udidahan.com/2011/04/22/when-to-avoid-cqrs/

http://codebetter.com/gregyoung/2012/09/09/cqrs-is-not-an-architecture-2/


3
「比較的複雑でコストのかかるパターン」部分を除くすべてに同意します。CQRSは、読み取りと書き込みを分離しているだけです。ダクトテープ、ミドルウェア/複雑なツールを使用せずに、以前と同じデータベースを維持して、すべてのことを行うことができます。
-guillaume31

@ guillaume31、それは公正な点です。私はそれが元の質問からのアイデアにかなり関連すると思う:「Web Apiではアクションはそれ自体が何らかのコマンド/クエリである」。しかし、コマンドとクエリに個別のクラスを使用しないCQRSサンプル(githubが望ましい)を見たことがありますか?これは、他の人がどのように.NETでCQRSを実装するかを確認しようとするときに見つけるものです。
SiberianGuy

はい、しかしそれは過剰設計ではありません。これはパターンの基本的な前提です。クエリを書き込みから分離し、読み取りモデルをドメインモデルから分離します。
-guillaume31

CQRSのアプローチは、多くの状況で過剰に殺されるかもしれませんが、それはまったく別の話です。QのCQRSに誤って起因する小さな技術的詳細のためにやり過ぎではありません。CQRSがもたらすものを常に必要としないため、やり過ぎです。
-guillaume31

ファウラーのポイントは特定のポイントに対してのみ有効だと思います。SQLビューはCQRSの一種であり、長年にわたって使用されており、非常に複雑だと言う人はいません。CQRSには多くのフレーバー、つまりイベントソーシングプロジェクションがあるため、一部のエリアでは複雑に見えますが、別のエリアでは些細なこともあります。
アレクセイ・ジマレフ

3

CQRSはリポジトリの1対1の置き換えではありません。これは、場合によってのみ有用な複雑でコストのかかるパターンだからです。

Udi Dahanが言うべきメリットは次のとおりです。

CQRS(およびイベントソーシングも)を使用するほとんどの人は、そうすべきではありません。

[...]

CQRSがアーキテクチャ的に間違っていることを示す、オンラインで表示されるサンプルアプリケーションのほとんどが申し訳ありません。また、エンティティスタイルの集約ルートCQRSモデルへと導くフレームワークについても非常に警戒します。

ソース

マーティン・ファウラー:

[...] CQRSの使用には非常に注意する必要があります。多くの情報システムは、読み取られるのと同じ方法で更新される情報ベースの概念によく適合します。そのようなシステムにCQRSを追加すると、かなり複雑になります。

ソース

最後に、グレッグヤング:

CQRSは、アーキテクチャパターンと呼ぶことができます。

[...]

これは、ほとんどのアーキテクチャパターンをあらゆる場所に適用するのは良くないことを理解するために非常に重要です。アーキテクチャガイドラインにアーキテクチャパターンが表示されている場合は、おそらく問題があります

[...]

イベントソーシングを使用している人々から見た最大の失敗は、どこでもそれを使用しようとすることです。

ソース

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.