针对不同过滤条件,打开封闭原理

时间:2014-07-15 03:04:28

标签: c# .net open-closed-principle

下面的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;}
}

3 个答案:

答案 0 :(得分: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
        }
    }

您甚至可以将其转换为通用命令(例如here)并通过它执行所有数据库逻辑,放弃&#34;服务&#34;反模式。

答案 1 :(得分:0)

我会有一个名为IFilter的接口,它负责FilterConstraints合同。

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");

Catch是你想再添加一个过滤器,你有一个新的类并将IFilter实现到该过滤器类并从product调用它。这是你的扩展但不修改类,保持打开和关闭原则

答案 2 :(得分:-3)

这里的要求是为每个新过滤器添加算法而不更改服务类。策略模式符合此要求。希望这有用。