0

以下のクラス ProductService は、データベースから日付、国などのさまざまなフィルターに基づいて製品を取得します。ProductsService は OCP に従いません。価格で製品を取得するなどの新しいフィルターを追加するには、ProductsService コードを変更する必要があるためです。どのように修正できますか?提案やコメントは本当に役に立ちます。

public class ProductsService : IProductsService
{
    public FilteredProducts GetProductsByDate(DateTime startDate, DateTime EndDate) 
    {   
        //.....

    }
    public FilteredProducts GetProductsByCountry(string country)
    {
        //.....

    }

    public FilteredProducts GetProductsByCity(string city) 
    {
        //.....

    }

}

public class FilteredProducts
{
    public IEnumerable<Product> Products{set;get;}
    public int uniqueProducts { set; get; }
}

public class Product
{
    public int ID{set;get;}
    public string Name{set;get;}
    public decimal Cost{set;get;}
}
4

3 に答える 3

1

最善の方法は、各操作を個別のクラスとして表すことです。

    public interface IProductFilter
    {
        FilteredProducts GetProducts(); 
    }

    public class GetProductsByDate : IProductFilter
    {
        private DateTime _startDate;
        private DateTime _endDate;

        public GetProductsByDate(DateTime startDate, DateTime EndDate)
        {
            _startDate = startDate;
            _endDate = EndDate;
        }

        public FilteredProducts GetProducts()
        {
            // filter
        }
    }

その後、この実装をサービスに渡すことができ、そこで実行されます。

    public class ProductsService : IProductsService
    {
        public FilteredProducts FilterProducts(IProductFilter filter)
        {
            // execute the filter
            // return the products
        }
    }

それを一般的なコマンド (たとえば、ここ) に変換し、それを介してすべてのデータベース ロジックを実行し、「サービス」アンチパターンを捨てることさえできます。

于 2014-07-15T04:09:37.067 に答える
0

FilterConstraints コントラクトを担当する IFilter というインターフェイスを用意します。

public interface IFilter
    {
        void FilterConstraints(String FilterConstraints);
    }

次に、フィルタリングを担当するクラスを用意し、それらのクラスに IFilter Inetrface を実装させます。

 public class FilterByCountry : IFilter
{
     public void FilterConstraints(string FilterConstraints)
     {
       //**Your Filter Constraints**/
     }
}

 public class FilterByCity : IFilter
{
     public void FilterConstraints(string FilterConstraints)
     {
         /**Your Filter Constraints **/
     }
}

これは、IFilter を初期化するコンストラクターを持つメイン クラスです (これはさまざまな FilterClassed で共通です)。

public class ProductService
{
    private IFilter _filter=null;

    public ProductService( IFilter Filter)
    {
        _filter = Filter;
    }


    public void FilterProducts(String Constraints)
    {
         _filter.FilterConstraints(Constraints);
    }
}

したがって、FilterByCountry に基づいて Filterbased を呼び出したい場合は、次のようになります。

var filterbycountry=new FilterByCountry();
var Filter=new ProductService(filterbycountry);
filter.FilterProducts("your constraints");

キャッチは、フィルターをもう 1 つ追加する場合、新しいクラスを作成し、そのフィルター クラスに IFilter を実装して、製品から呼び出すことです。これは、クラスを拡張しますが、クラスを変更するのではなく、オープンとクローズの原則を維持します。

于 2014-07-15T03:52:35.507 に答える