开合原理适用于不同的过滤条件

本文关键字:过滤 条件 适用于 | 更新日期: 2023-09-27 18:12:50

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

开合原理适用于不同的过滤条件

最好的方法是将每个操作表示为单独的类。

    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
        }
    }

您甚至可以将其转换为通用命令(例如这里)并通过它执行所有数据库逻辑,从而抛弃"服务"反模式。

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

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

然后我将有负责过滤的类,并让这些类实现过滤器接口。

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

如果你想调用Filterbased on FilterByCountry,它会是

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

Catch是如果你想添加一个过滤器,你需要有一个新类并实现过滤器到那个过滤器类并从product中调用它。这是你的扩展,但不修改类,保持开放和封闭的原则

这里的要求是在不更改服务类的情况下为每个新过滤器添加算法。策略模式符合这一要求。