4

私は次の基本的なエンティティを持っています:

public class Basket
{
    public List<Product> Products {get;set;}
}

public class Product
{
    public string Name {get;set;}
    public decimal Price {get;set;}
}

そして、固定価格を下回るバスケット内のすべての製品のリストを取得したいと思います。このためのロジックはBasket、次のようになります。

public class Basket
{
    public List<Product> Products {get;set;}
    public List<Product> CheapProducts
    {
        get { return Products.Where(p => p.Price < 5).ToList(); }
    }
}

または、サービスクラスにProductFilterer入れる必要があります。これは、製品のリスト全体をパラメーターとして受け取り、フィルター処理された製品のリストを返します。それとも、呼び出し元のクラスのメソッドに直接入る必要がありますか?

または、他の何か?このためのベストプラクティスは何ですか?

4

4 に答える 4

2

仕様パターンを調べることを検討してください。リンクには優れた実装例がありますが、要するに、このパターンを使用すると、単純な述語(または仕様)に基づいて複雑な選択基準を作成できます。

デリゲートを使用したこのようなパターンの迅速な(そして不完全な)実装は、次のように行うことができます。

public class Specification<T>
{
    Func<T, bool> _spec;
    public Specification(Func<T, bool> spec)
    {
        _spec = spec;
    }

    public bool IsSatisifedBy(T item)
    {
        return _spec(T);
    }
}

// ...

_cheapProductsSpecification = new Specification<Product>(p => p.Price < 5);
var cheapProducts = Basket.Products.Where(p => _cheapProductsSpecification.IsSatifisifedBy(p));

もちろん、これは単純でおそらく冗長な例ですが、And、Or、およびNotを追加すると(リンクを参照)、複雑なビジネスロジックを仕様変数に組み込むことができます。

于 2012-05-29T14:09:59.507 に答える
2

私がすることは、「安価な製品」の概念がファーストクラスのドメインの概念であり、ユビキタス言語で導入されなければならないかどうかをドメインの専門家に確認することです。

この場合、Steveの仕様ソリューションは問題をエレガントな方法で解決します。

安さは重要ではないか、それほど明確に定義されていない場合(たとえば、安さのしきい値がアプリケーション全体で異なる場合)、そのための特定のエンティティを作成する必要はなく、コードの呼び出しで必要なときに関連する基準でBasket.Productsをフィルタリングするだけです。 。

于 2012-05-29T15:41:12.827 に答える
0

はい、DTOをビジネスロジックから分離しておくことをお勧めします。私は、データオブジェクトを、データアクセス、ビジネス、およびUIレイヤーとは完全に別のレイヤーであると考えるのが好きです。より一般的なProductBusinessクラスがある場合は、別のフィルタークラスがあると本当に便利でない限り、そこに配置することをお勧めします。

于 2012-05-29T13:41:05.907 に答える
0

あなたのBasketクラスは、直接フィルタリングする方法を知らないはずです。あなたが提案したように、ProductFilterから結果を返すことを可能にする公開された関数を持っているのは正しいことです。コードの外観は次のようになります。

class ProductFilter  
{  
    filterCheapProducts(Collection<Product> productsToFilter)  
    {  
       return Products.Where(p => p.Price < 5).ToList(); //I assume your code is correct  
    }    
}  

class Basket  
{  
    Collection<Product>  getCheapProducts()  
    {  
            return filter.filterCheapProducts(this.products);  
    }  
}  
于 2012-05-29T13:44:15.290 に答える