开合原理适用于不同的过滤条件
本文关键字:过滤 条件 适用于 | 更新日期: 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中调用它。这是你的扩展,但不修改类,保持开放和封闭的原则
这里的要求是在不更改服务类的情况下为每个新过滤器添加算法。策略模式符合这一要求。