针对不同过滤条件的开闭原理
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”在几分钟前添加了上述模式的示例代码。以上是关于针对不同过滤条件的开闭原理的主要内容,如果未能解决你的问题,请参考以下文章