一:实际场景介绍

我们在给用户做订单催付通知的时候,会有这样的一种场景,用户在系统后台设置一组可以催付的规则,比如说订单金额大于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. 最后我们客户端调用程序就简单了,只要将“原子性”的过滤条件追加到“逻辑运算类”中就完美了,如下图:


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" });//追加filter条件var filterList = new IFilter[3] {new RegularIDFilter(),new RegularNameFilter(),new RegularCondtionFilter()};var andCriteria = new AndFilter(filterList.ToList());//进行 And组合 过滤andCriteria.Filter(regulars);}}

当你仔细看完上面的代码,会不会发现,如果后续有需求变更,比如说增加筛选的维度,我只需要新增一个继承 IFilter 的子类就搞定了,客户端在调用的时候只要在Filters集合中追加该筛选维度,是不是就OK了,所以这种模式几乎达到了无代码修改的地步~~~好了,本篇就说到了这里,希望对你有帮助~

使用过滤器模式,让客户关怀中的代码更加干净整洁相关推荐

  1. 从真实项目中抠出来的设计模式——第二篇:过滤器模式

    一:实际场景介绍 我们在给用户做订单催付通知的时候,会有这样的一种场景,用户在系统后台设置一组可以催付的规则,比如说订单金额大于xx元,非黑名单用户,来自 哪个地区,已购买过某个商品,指定某个营销活动 ...

  2. 企业常用的客户关怀方法,你了解几个?

    在以客户为中心的商业模式中,客户关怀是客户维护的重要方面.随着竞争的日益激烈,企业依靠基本的售后服务已经不能满足客户需要,必须提供主动的.超值的.让客户感动的关怀性服务才能赢得客户信任. 中国有一句古 ...

  3. SAP SD-销售模式-寄售(客户寄售)

    1. 业务背景 业务背景1如下: 某公司供应日用品给某大型连锁超市,平时按照正常节奏发货给超市,但此发货并非结算依据,每月底超市根据当月流水中销售给消费者的数量,与该公司进行结算,剩余未销售部分仍然为 ...

  4. java filter 模式,Java设计模式----过滤器模式(挑三拣四)

    过滤器模式 描述 拦截过滤器模式(Intercepting Filter Pattern)用于对应用程序的请求或响应做一些预处理/后处理.定义过滤器,并在把请求传给实际目标应用程序之前应用在请求上.过 ...

  5. 设计模式 过滤器模式

    过滤器模式(Filter Pattern)或标准模式(Criteria Pattern) 是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来.这种 ...

  6. 设计模式笔记八:过滤器模式

    原文:http://www.runoob.com/design-pattern/ 少许个人理解,如有错误请指出.欢迎一起讨论.(本文基本摘抄) 定义: 过滤器模式(Filter Pattern)或标准 ...

  7. pbl和sbl_PBL与SBL联合教学模式在妇产科教学中的应用研究

    PBL 与 SBL 联合教学模式在妇产科教学中的应用研究 陈静,刘彩霞▲,王颖,崔红 [摘 要] [摘要]目的 探索 PBL 与 SBL 联合教学模式在妇产科教学中的应用效 果.方法 在 98 期七年 ...

  8. 计算机网络对等模式,计算机网络有两种常用的工作模式,它们是对等模式和客户/服务器模式。QQ聊天属于________模式。...

    计算机网络有两种常用的工作模式,它们是对等模式和客户/服务器模式.QQ聊天属于________模式. 更多相关问题 Maria, Enclosed is the schedule for this y ...

  9. 计算机网络有客户 服务器和对等模式,四种网络工作模式有:对等模式、客户/服务器模式以及( )、( ),...

    四种网络工作模式有:对等模式.客户/服务器模式以及专用服务器模式和浏览器/服务器模式. 1.对等模式(P2P,peer-to-peer)是一种通信模式,其中每一方都拥有相同的功能,任何一方都可以启动通 ...

最新文章

  1. exchange无法收发邮件_SpringBoot2.x系列教程69--SpringBoot中整合邮件发送
  2. Python中通常不应该犯的7个错误
  3. php 函数strtr 替换函数实例解析 strtr 速度比较快
  4. JavaScript中的两个等号(==)和三个等号(===)
  5. 京东量化平台宣告下线,其他平台该何去何从?
  6. 人口各省预测模型matlab_利用matlab编程求解人口预测模型.doc
  7. [CTF]RAR加密原理
  8. wifi分析仪怎么看哪个信道好_四大实用WiFi检测工具,调整信道避免干扰
  9. PHP-FPM 性能优化
  10. 计算机显示错误屏幕,如何解决显示器分辨率错误
  11. 车间生产管理(二)· 设备综合利用率 OEE 解决方案-可部署在 Power BI 上的设备 OEE 解决方案
  12. PHP实现图片上传功能
  13. 用百行Python代码写一个关于德州扑克的类
  14. Python:短网址
  15. SizeBalanceTree详解(含代码实现)
  16. 汇编语言: 从键盘上输入一串字符(用回车键结束,使用 10 号功能调用。)放在 STRING 中,试 编制一个程序测试字符串中是否存在数字。如有,则把 CL 的第 5 位置 1,否则将该位置置 0。
  17. 共享淡雅型产品分析商务PPT模板
  18. 初学者计算机学什么软件好,「推荐」初学者学电脑绘画用什么软件
  19. 我和嵌入式的那些事儿
  20. 【Python编程】图片缩放

热门文章

  1. 前端工程构建工具——Yeoman
  2. mysql配置-django
  3. linux slub分配器浅析
  4. [for循环之等腰三角形]
  5. Linux 内核中断内幕【转】
  6. win 7 旗舰版镜像 注入USB3.0 驱动
  7. 第十周项目1-程序填充与阅读(三)
  8. TCP连接——三次握手和四次断开
  9. Linux虚拟文件系统(VFS)
  10. SharePoint 2007 Select People and Groups中搜索不到其他Domain账户的问题[已解决]