从真实项目中抠出来的设计模式——第二篇:过滤器模式
一:實際場景介紹
? ? ?我們在給用戶做訂單催付通知的時候,會有這樣的一種場景,用戶在系統后臺設置一組可以催付的規則,比如說訂單金額大于xx元,非黑名單用戶,來自
哪個地區,已購買過某個商品,指定某個營銷活動的人等等這樣的條件,如果這時用戶在淘寶上下了一個訂單,那程序要判斷的就是看一下此訂單是否滿足這
些規則中的某一個,如果滿足,我們給他發送催付通知,這種場景是很多做CRM的同學都會遇到的問題,那針對這種場景,如何更好的規劃業務邏輯呢?
?
二:普通的編程代碼?
? ? 在這里我們就不考慮多篩選條件下的性能,而只從代碼維護復雜度考慮,如果不清楚設計模式的同學,大概會寫出如下的代碼:
namespace ConsoleApplication1
{
? ? class Program
? ? {
? ? ? ? static void Main(string[] args)
? ? ? ? {
? ? ? ? ? ? var regulars = new List<Regulars>();
? ? ? ? ? ? regulars.Add(new Regulars() { RegularID = 1, RegularName = "規則1", AnalysisConditons = "xxxx" });
? ? ? ? ? ? regulars.Add(new Regulars() { RegularID = 1, RegularName = "規則2", AnalysisConditons = "xxxx" });
? ? ? ? ? ? regulars.Add(new Regulars() { RegularID = 1, RegularName = "規則3", AnalysisConditons = "xxxx" });
? ? ? ? ? ? regulars.Add(new Regulars() { RegularID = 1, RegularName = "規則4", AnalysisConditons = "xxxx" });
? ? ? ? ? ? regulars.Add(new Regulars() { RegularID = 1, RegularName = "規則5", AnalysisConditons = "xxxx" });
? ? ? ? ? ? var filters = FilterRegularID(regulars);
? ? ? ? ? ? filters = FilterRegularName(filters);
? ? ? ? ? ? filters = FilterCondtions(filters);
? ? ? ? ? ? //... 后續邏輯
? ? ? ? }
? ? ? ? static List<Regulars> FilterRegularID(List<Regulars> persons)
? ? ? ? {
? ? ? ? ? ? //過濾 “姓名” 的邏輯
? ? ? ? ? ? return null;
? ? ? ? }
? ? ? ? static List<Regulars> FilterRegularName(List<Regulars> persons)
? ? ? ? {
? ? ? ? ? ? //過濾 “age” 的邏輯
? ? ? ? ? ? return null;
? ? ? ? }
? ? ? ? static List<Regulars> FilterCondtions(List<Regulars> persons)
? ? ? ? {
? ? ? ? ? ? //過濾 “email” 的邏輯
? ? ? ? ? ? return null;
? ? ? ? }
? ? }
? ? /// <summary>
? ? /// 各種催付規則
? ? /// </summary>
? ? public class Regulars
? ? {
? ? ? ? public int RegularID { get; set; }
? ? ? ? public string RegularName { get; set; }
? ? ? ? public string AnalysisConditons { get; set; }
? ? }
}
為了演示,上面的代碼是從regularid,regularname,condition三個維度對regulars這個聚合對象進行AND模式的篩選過濾,當過濾維度比較多的時候,這種寫法看的出來是簡單粗暴,維護起來也必須簡單粗暴, 所以上萬行代碼也就是這么出來的,設計模式告訴我們一個簡單的“開閉原則”,那就是追求最小化的修改代碼,這種場景有更好的優化策略嗎?對應到設計模式上就是“過濾器模式”,專門針對這種場景的解決方案,一個維度一個類,然后通過邏輯運算類將他們進行組合,可以看出這是一種“結構式的設計模式”。
?
三:過濾器模式
? ?好了,廢話不多說,先來看一下優化后的設計圖紙如下:
從上面這張圖紙中可以看到,我已經將三個維度的過濾方法提取成了三個子類,由此抽象出了一個IFilter接口,當然你也可以定義成抽象類,然后實現了兩個運算級AND和OR子類Filter,用于動態的對原子性的RegularIDFilter,RegularNameFilter,ReuglarCondtionFilter進行AND,OR邏輯運算,下面我們再看具體代碼:
?
1.IFilter
public interface IFilter{List<Regulars> Filter(List<Regulars> regulars);}?
2. RegularIDFilter
public class RegularIDFilter : IFilter
? ? {
? ? ? ? /// <summary>
? ? ? ? /// Regulars的過濾邏輯
? ? ? ? /// </summary>
? ? ? ? /// <param name="regulars"></param>
? ? ? ? /// <returns></returns>
? ? ? ? public List<Regulars> Filter(List<Regulars> regulars)
? ? ? ? {
? ? ? ? ? ? return null;
? ? ? ? }
? ? }
3.RegularNameFilter
? ??? ??
public class RegularNameFilter : IFilter
? ? {
? ? ? ? /// <summary>
? ? ? ? /// regularName的過濾方式
? ? ? ? /// </summary>
? ? ? ? /// <param name="regulars"></param>
? ? ? ? /// <returns></returns>
? ? ? ? public ?List<Regulars> Filter(List<Regulars> regulars)
? ? ? ? {
? ? ? ? ? ? return null;
? ? ? ? }
? ? }
4.?RegularCondtionFilter
public class RegularCondtionFilter : IFilter
? ? {
? ? ? ? /// <summary>
? ? ? ? /// Condition的過濾條件
? ? ? ? /// </summary>
? ? ? ? /// <param name="regulars"></param>
? ? ? ? /// <returns></returns>
? ? ? ? public ?List<Regulars> Filter(List<Regulars> regulars)
? ? ? ? {
? ? ? ? ? ? return null;
? ? ? ? }
? ? }
5.AndFilter
/// <summary>
? ? /// filter的 And 模式
? ? /// </summary>
? ? public class AndFilter : IFilter
? ? {
? ? ? ? List<IFilter> filters = new List<IFilter>();
? ? ? ? public AndFilter(List<IFilter> filters)
? ? ? ? {
? ? ? ? ? ? this.filters = filters;
? ? ? ? }
? ? ? ? public List<Regulars> Filter(List<Regulars> regulars)
? ? ? ? {
? ? ? ? ? ? var regularlist = new List<Regulars>(regulars);
? ? ? ? ? ? foreach (var criteriaItem in filters)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? regularlist = criteriaItem.Filter(regularlist);
? ? ? ? ? ? }
? ? ? ? ? ? return regularlist;
? ? ? ? }
? ? }
6.OrFilter
public class OrFilter : IFilter
? ? {
? ? ? ? List<IFilter> filters = null;
? ? ? ? public OrFilter(List<IFilter> filters)
? ? ? ? {
? ? ? ? ? ? this.filters = filters;
? ? ? ? }
? ? ? ? public List<Regulars> Filter(List<Regulars> regulars)
? ? ? ? {
? ? ? ? ? ? //用hash去重
? ? ? ? ? ? var resultHash = new HashSet<Regulars>();
? ? ? ? ? ? foreach (var filter in filters)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? var smallPersonList = filter.Filter(regulars);
? ? ? ? ? ? ? ? foreach (var small in smallPersonList)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? resultHash.Add(small);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? return resultHash.ToList();
? ? ? ? }
? ? }
7. 最后我們客戶端調用程序就簡單了,只要將“原子性”的過濾條件追加到“邏輯運算類”中就完美了,如下圖:
當你仔細看完上面的代碼,會不會發現,如果后續有需求變更,比如說增加篩選的維度,我只需要新增一個繼承IFilter的子類就搞定了,客戶端在調用的時候只要
在Filters集合中追加該篩選維度,是不是就OK了,所以這種模式幾乎達到了無代碼修改的地步~~~好了,本篇就說到了這里,希望對你有幫助~
相關文章;
從真實項目中摳出來的設計模式——第一篇:策略模式
原文地址:http://www.cnblogs.com/huangxincheng/p/6415393.html
.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注
總結
以上是生活随笔為你收集整理的从真实项目中抠出来的设计模式——第二篇:过滤器模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在IIS上部署你的ASP.NET Cor
- 下一篇: asp.net ajax控件工具集 Au