针对不同过滤条件的开闭原理

Posted

技术标签:

【中文标题】针对不同过滤条件的开闭原理【英文标题】:Open closed principle for different filter conditions 【发布时间】:2014-07-15 03:04:28 【问题描述】:

下面的 ProductService 类根据不同的过滤器(例如按日期、国家/地区等)从数据库中获取产品。 ProductsService 不遵循 OCP,因为添加新过滤器(如按价格获取产品)需要更改 ProductsService 代码。如何修复?任何建议/cmets 都会非常有帮助。

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> Productsset;get;
    public int uniqueProducts  set; get; 


public class Product

    public int IDset;get;
    public string Nameset;get;
    public decimal Costset;get;

【问题讨论】:

【参考方案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)并通过它执行所有数据库逻辑,放弃“服务”反模式。

【讨论】:

【参考方案2】:

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

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 的过滤器,就像

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

Catch 是如果您想再添加一个过滤器,您将拥有一个新类并将 IFilter 实现到该过滤器类并从产品中调用它。这是您扩展但不修改类,保持打开和关闭原理

【讨论】:

如果您有多个过滤器,但只有一项服务,这将不会真正起作用。当您的服务是长期/单例时。通常是这种情况。【参考方案3】:

这里的要求是在不改变服务类的情况下为每个新过滤器添加算法。策略模式符合这一要求。希望这会有所帮助。

【讨论】:

其实,不,没有用。请在您的描述中添加更多详细信息(如何做而不是做什么)并包含一些代码,因为原始发布者已努力这样做。 对不起。我的错。用户“restless”在几分钟前添加了上述模式的示例代码。

以上是关于针对不同过滤条件的开闭原理的主要内容,如果未能解决你的问题,请参考以下文章

带构造函数的开闭原理

开闭固原则条件失败

git中使用.gitignore文件

布隆过滤器-原理时间复杂度空间复杂度不支持删除

布隆过滤器-原理时间复杂度空间复杂度不支持删除

布隆过滤器-原理时间复杂度空间复杂度不支持删除