2

他のデザイン パターンと同様に、仕様パターンは優れたコンセプトですが、熱心なアーキテクト/開発者が使いすぎてしまいがちです。

私は新しいアプリケーション (.NET & C#) の開発を開始しようとしていますが、仕様パターンの概念が非常に気に入っており、それを最大限に活用したいと思っています。しかし、全力を尽くす前に、アプリケーションの開発で仕様パターンを使用するときに経験した問題点を誰かが共有できるかどうかを知りたいと思います。

理想的には、他の人が問題を抱えているかどうかを確認しています

  • 仕様パターンに対する単体テストの記述
  • 仕様が存在するレイヤーの決定 (リポジトリ、サービス、ドメインなど)
  • if単純なステートメントで仕事ができたときに、どこでもそれを使用する
  • 等?

前もって感謝します

4

3 に答える 3

16

LINQ が仕様パターンの代わりになるとは思いません。ビジネス ロジックをカプセル化するには、仕様を使用するのが最適です。したがって、私のビジネス要件の 1 つで、いくつかの機能についてすべての大切な顧客を獲得する必要がある場合、Linq ステートメントは次のようになります。

var valuedCustomers = Customers.Where(c => c.Orders.Count > 15 && c.Active).ToList();

このステートメントをアプリケーション全体に入力できますが、そのルールに、顧客がある日付より前に参加しなければならないというルールを追加したい場合はどうすればよいでしょうか? さて、アプリケーション全体を調べて、Linq を変更する必要があります。または、オブジェクト グラフが変更された場合 (ただし、これがパターンを使用する唯一の理由ではありません)。代わりに、このようなことをすることができたとき

var valuedCustomers = Customers.Where(new ValuedCustomerRule.IsSatisfied()).ToList();

パターンが過剰に使用されていることに同意しますが、システム全体に表示されるビジネス ルールに非常に役立つため、それらのルールが変更されたときに噛まれることはありません。私にとっては、アプリケーション コード全体に SQL クエリを残すようなものです。

于 2010-11-04T22:23:43.157 に答える
8

David がコメントで指摘したように、仕様に関して有用なことの多くは、LINQ などを使用してより簡潔に実現できるようになりました。

新しい仕様タイプの代わりに、オンザフライで任意の仕様を作成できます。 GetCustomers().Where(customer => customer.IsActive && customer.City == "Oakland");

ただし、これは仕様を完全に置き換えるものではありませんが、いくつかの理由があります。

  1. すべての顧客を返した後、消費クラスでソート/フィルタリングが行われます。メモリ内オブジェクト以外のものを扱っている場合、これは最適ではありません (LINQ-to-SQL などは例外です。クエリをコンパイルおよび最適化し、サーバー/リモート側で実行して、目的の結果のみを返すためです)。 )。
  2. コレクションを公開し、仕様を LINQ クエリに任せれば、API はあらゆるクエリに対して広く開かれています。何をどれだけ取得できるかを制限したい場合は、クエリに使用する一連の仕様が必要になります。

確かにどこでも使用する必要はありません。また、まったく必要ない可能性も十分にあります。あなたのドメインや何に取り組んでいるのかわかりません。

最善のアドバイスは、それを使用しようとしないことだと思います。それがいつ保証されるかは、あなたがリンク先の記事の最初の例のようなクラスを書き始めたときにわかるでしょう。

必要に応じて取得できるように、メンタル パターン リポジトリに保管しておいてください。まったく使用しない場合は、必要がなかったことを意味するだけであり、それで問題ありません。

レイヤーの選択は、仕様と用途の性質に左右されます。多くの場合、それらはサービス層をサポートするヘルパーですが、場合によってはドメイン ロジックをカプセル化します。

単体テストに関しては、仕様が単位であるか、または単位を含んでいることに注意してください。可能なすべての仕様の組み合わせで仕様を受け入れるメソッドをテストしないでください。仕様自体をテストして、期待どおりに動作することを確認すると、多くのメソッドやクラスで同じ仕様を自信を持って再利用できます。

それが少し役立つことを願っています。

于 2010-03-24T12:40:08.783 に答える
1

更新された回答: Wix に同意します。LINQ は仕様パターンの代わりにはなりません。Wix の回答にコメントを追加するのに十分な評判がありません。回答として返信しているだけです。

この論文によると、仕様は主にドメインオブジェクトをステートメントと照合するために使用されます。仕様はドメイン オブジェクトとの照合時に true/false を返しますが、これは仕様がコード内のブール条件をカプセル化するために提案されているという意味ではありません。

Wixの回答をさらに続けます。ValuedCustomer 仕様を定義している場合は、ルールを使用する別の可能性があります。

   var valuedCustomer = new ValuedCustomerSpecification();
   //1. You can use this statement to check if a customer is valued or not in your domain
   Customer customer = ....
   if(valuedCustomer.IsSatisfiedBy(customer))
   
   //2. You can use it to get just valued customers from repository, 
   var valuedCustomers = repository.Get(valuedCustomer);
   
   //3. You can combine it with other specifications to create composite specifications. Following syntax can vary with implementation
   var seniorValuedCustomer = valuedCustomer.And(seniorCustomer)

からの私の理解では、必要性があり、アプリの UI で許可されていれば、ユーザーは仕様とやり取りして目的を達成できます。

上記の論文では、仕様パターンを使用しない場合についても言及しています。

于 2015-09-02T10:06:36.123 に答える