2

仕様パターンは、実装するクラスの階層を使用してISpecification<T>、型 T の候補オブジェクトが特定の仕様に一致する (= ビジネス ルールを満たす) かどうかを評価する方法を説明していることを知っています。

私の問題:実装したいビジネスルールは、いくつかのオブジェクト(顧客と契約など)を評価する必要があります。

私の二重の質問:

  • これを達成するための仕様パターンの典型的な適応はありますか? ISpecification<T>仕様クラスによるの実装を削除し、メソッドで必要な数のパラメーターを取得することしか考えられませんisSatisfiedBy()。しかし、これを行うと、この仕様を他の仕様と組み合わせることができなくなります。

  • この問題は私の設計の欠陥を明らかにしますか? (つまり、顧客と契約を使用して評価する必要があるものは、必要なすべての情報を含むサブスクリプションなどの別のオブジェクトで評価する必要があります) ?

4

4 に答える 4

5

その場合(仕様が正確に何をすべきかに応じて、オブジェクトの1つを仕様のサブジェクトとして使用し、他のオブジェクトをパラメーターとして使用します。

例:

public class ShouldCreateEmailAccountSpecification : ISpecification<Customer>
{
    public ShouldCreateEmailAccountSpecification(Contract selectedContract)
    {
       SelectedContract = selectedContract;
    }

    public Contract SelectedContract { get; private set; }

    public bool IsSatisfiedBy(Customer subject)
    {
        return false;
    }
}
于 2010-02-24T22:40:27.767 に答える
2

問題は、仕様インターフェイスがジェネリック型パラメーターを使用していることです。これにより、ISpecification<Customer> は実際には ISpecification<Contract> とは異なるインターフェイスであるため、異なる専門化 (Customer、Contract) 間で評価ロジックを組み合わせるために使用できなくなります。上記のジェフのアプローチを使用できます。これは、型パラメーターを取り除き、すべてを基本型 (オブジェクト) として渡します。使用している言語によっては、レベルを引き上げて、デリゲートを使用して仕様をブール論理と組み合わせることができる場合もあります。C# の例 (書かれている限り特に有用ではありませんが、フレームワークのアイデアが得られるかもしれません):

ISpecification<Customer> cust_spec = /*...*/
ISpecification<Contract> contract_spec = /*... */
bool result = EvalWithAnd( () => cust_spec.IsSatisfiedBy(customer), () => contract_spec.IsSatisfiedBy( contract ) );

public void EvalWithAnd( params Func<bool>[] specs )
{
    foreach( var spec in specs )
    {
       if ( !spec() )
          return false; /* If any return false, we can short-circuit */
    }
    return true; /* all delegates returned true */
}
于 2010-02-24T16:56:11.443 に答える
0

あなたの質問を理解したかどうかはわかりません。

顧客と契約の両方に同じ仕様を使用している場合、これは、両方に同じメッセージを送信できることを意味します。これは、インターフェイスを実装し、このインターフェイスをTタイプとして使用するように両方を作成することで解決できます。これがあなたのドメインで意味があるかどうかはわかりません。

これがあなたの質問に対する答えではない場合は申し訳ありません。

于 2010-03-27T18:42:09.513 に答える