本文用到的编程语言为C#,具体思路不限制编程语言。

刚才正在浏览http://ruby-china.org/topics/7384的时候,看到5楼的回复,突然有一种想法,不知道优劣,请大家帮忙评判一下,或者给出一些更好的实现方案。

我们先来上一段代码,就是常见的一种代码。

  1. Order getOrder(string orderNo)
  2. {
  3. order = repo.getOrder(orderNo);
  4. if(order.condition1)
  5. {
  6. ...
  7. }
  8. if(order.condition2)
  9. {
  10. ...
  11. }
  12. if(order.condition3)
  13. {
  14. ...
  15. }
  16. .
  17. .
  18. .
  19. }

上面是一段伪代码,实现的就是一个根据订单号,获取订单,然后根据订单的一些条件进行一些处理。

order是获取出来的订单,condition1、condition2、condition3是一些条件。随着业务的复杂,condition3后面还可能更多的condition,就需要添加更多的if,进行更多的判断,然后这个方法越来越长,越来越难以读懂,越来越难以维护,越来越。。。

我想是不是可以换个角度,不是订单来判断条件,然后执行一些代码。而是订单进入一个处理流程,然后处理流程中有很多的闸门,每个闸门代表一个特征条件处理器,然后由这个处理器来判断流经自己的订单是否符合条件,符合就处理,不符合就掠过。

这样有几个好处:

  1. 上面代码中的获取订单方法,不会越来越长,这样阅读起来就很好理解,在后面进行维护的时候,就很容易来做了。
  2. 添加一个新的条件处理分支也很容易,只要把这种条件处理看做是一个闸门,在处理流水线中加入新闸门就可以了,其他的都不需要变化。
  3. 调整原来的条件处理,也只需要修改闸门内部的处理代码即可,不用担心是否影响其他处理分支。
  4. 分支独立之后,还可以针对每个分支做单元测试。

其实扩展开来想,这个流程不仅可以处理订单,任何针对一个对象进行流程化处理的场景,都可以套用上面的代码结构,都可以得到上面的好处。

我画了一个示意图。

图 1.1 对象处理流水线

放出一段示例代码。

  1. public interface IRepo
  2. {
  3. string getOrder(string orderNo);
  4. }
  5. public class Repo : IRepo
  6. {
  7. public string getOrder(string orderNo)
  8. {
  9. return string.Empty;
  10. }
  11. }
  12. public class Client
  13. {
  14. public void getOrder(string orderNo)
  15. {
  16. var order = new Repo().getOrder(orderNo);
  17. var pipeline = new Pipeline();
  18. var handle1 = new condition1_Handle();
  19. var handle2 = new condition2_Handle();
  20. pipeline.add_order(order);
  21. pipeline.add_handle(handle1);
  22. pipeline.add_handle(handle2);
  23. pipeline.processOrder();
  24. }
  25. }
  26. class Pipeline
  27. {
  28. private List<IHandle> _handles;
  29. private string _order;
  30. public Pipeline()
  31. { _handles = new List<IHandle>(); }
  32. internal void add_order(string order)
  33. {
  34. this._order = order;
  35. }
  36. internal void add_handle(IHandle handle1)
  37. {
  38. _handles.Add(handle1);
  39. }
  40. internal void processOrder()
  41. {
  42. foreach (var h in _handles)
  43. {
  44. h.process(_order);
  45. }
  46. }
  47. }
  48. public interface IHandle
  49. {
  50. void process(string order);
  51. }
  52. public class condition1_Handle : IHandle
  53. {
  54. public  void process(string _order)
  55. {
  56. throw new NotImplementedException();
  57. }
  58. }
  59. public class condition2_Handle : IHandle
  60. {
  61. public void process(string _order)
  62. {
  63. throw new NotImplementedException();
  64. }
  65. }

感觉有点像是策略模式,但是感觉又不太像。

上面的代码还有优化的空间,大家有没有更好的方案呢,欢迎大家一起讨论!

稍加改进,引入泛型,就可以支持任意类型的对象处理。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. namespace ConsoleClient.Pipeline
  6. {
  7. public interface IRepo
  8. {
  9. Purchase getOrder(string orderNo);
  10. Product getProduct(int id);
  11. }
  12. public class Repo : IRepo
  13. {
  14. public Purchase getOrder(string orderNo)
  15. {
  16. return new Purchase();
  17. }
  18. public Product getProduct(int id)
  19. {
  20. return new Product();
  21. }
  22. }
  23. public class Client
  24. {
  25. public Purchase getOrder(string orderNo)
  26. {
  27. var order = new Repo().getOrder(orderNo);
  28. var pipeline = new Pipeline<Purchase>();
  29. var handle1 = new condition1_orderHandle();
  30. var handle2 = new condition2_orderHandle();
  31. pipeline.add_order(order);
  32. pipeline.add_handle(handle1);
  33. pipeline.add_handle(handle2);
  34. pipeline.processOrder();
  35. return order;
  36. }
  37. public Product getProduct(int id)
  38. {
  39. var product = new Repo().getProduct(id);
  40. var pipeline = new Pipeline<Product>();
  41. var handle1 = new condition1_productHandle();
  42. var handle2 = new condition2_productHandle();
  43. pipeline.add_order(product);
  44. pipeline.add_handle(handle1);
  45. pipeline.add_handle(handle2);
  46. pipeline.processOrder();
  47. return product;
  48. }
  49. }
  50. public class Pipeline<T>
  51. {
  52. private List<IHandle<T>> _handles;
  53. private T _order;
  54. public Pipeline()
  55. { _handles = new List<IHandle<T>>(); }
  56. public void add_order(T order)
  57. {
  58. this._order = order;
  59. }
  60. public void add_handle(IHandle<T> handle1)
  61. {
  62. _handles.Add(handle1);
  63. }
  64. public void processOrder()
  65. {
  66. foreach (var h in _handles)
  67. {
  68. h.process(_order);
  69. }
  70. }
  71. }
  72. public class Purchase
  73. {
  74. public bool IsPay { get; set; }
  75. }
  76. public class Product
  77. {
  78. public bool IsExpired { get; set; }
  79. }
  80. public interface IHandle<T>
  81. {
  82. void process(T order);
  83. }
  84. public class condition1_orderHandle : IHandle<Purchase>
  85. {
  86. public void process(Purchase order)
  87. {
  88. if (order.IsPay == false )
  89. {
  90. Console.WriteLine("you don't pay money");
  91. }
  92. }
  93. }
  94. public class condition2_orderHandle : IHandle<Purchase>
  95. {
  96. public void process(Purchase order)
  97. {
  98. }
  99. }
  100. public class condition1_productHandle : IHandle<Product>
  101. {
  102. public void process(Product product)
  103. {
  104. }
  105. }
  106. public class condition2_productHandle : IHandle<Product>
  107. {
  108. public void process(Product product)
  109. {
  110. }
  111. }
  112. }

本文转自 virusswb 51CTO博客,原文链接:http://blog.51cto.com/virusswb/1081790,如需转载请自行联系原作者

利用流水线改进代码中的if处理流程相关推荐

  1. jeeplus代码中配置并开发流程

    需求 流程绘制 一.配置流程 在流程工具类ActUtils.java中配置(添加)流程信息 二.在前台leaveList页面添加使用流程的触发事件(提交按钮) 三.编写代码[本文仅针对流程(提交事件) ...

  2. python代码物理_利用python求解物理学中的双弹簧质能系统详解

    前言 本文主要给大家介绍了关于利用python求解物理学中双弹簧质能系统的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 物理的模型如下: 在这个系统里有两个物体,它们的质 ...

  3. python对excel数据更改_利用python对excel中一列的时间数据更改格式代码示例

    本篇文章小编给大家分享一下利用python对excel中一列的时间数据更改格式代码示例,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. 问题场景:需要将 ...

  4. 自检代码中trustmanager漏洞_Windows内核漏洞利用教程

    堆栈溢出漏洞 首先,我们将从HackSysExtremeVulnerableDriver中的vanilla栈溢出漏洞开始讲起. 当向堆栈上的缓冲区存放的数据超出其存储容量时(例如,向16字节缓冲区(这 ...

  5. html天气插件iframe,HTML_利用iframe在网页中显示天气附效果截图,css: 复制代码代码如下: *{margi - phpStudy...

    利用iframe在网页中显示天气附效果截图 css: 复制代码代码如下: *{margin:0;padding:0;list-style-type:none;} a,img{border:0;} bo ...

  6. Unity 在代码中利用Mesh实时生成圆环/空心圆柱

    本篇文章主要介绍了利用Unity中的mesh 实时生成圆环的过程以及思想,我会在开头直接放出源码.如若有任何疑问,可向后继续观看详细解说~~~ (PSPSPS:Mesh生成的顺序,方式等有很多,当前代 ...

  7. C语言系列(二):最近重拾C语言的想法,谈到C中易错点,难点;以及开源代码中C语言的一些常用技巧,以及如何利用define、typedef、const等写健壮的C程序...

    写在前面的话:本系列主要是自己在c语言运用时,对一些不了解,但开源代码中常用的技巧,和一些c语言中偏门和易错点进行解析. 加入了自己的分析,如果不到位请多海涵,另外,引用一些非常好的文章(都有引用li ...

  8. android在代码中利用Spinner控件设置联动地区的解决办法

    需求就是地区选择可以弹出来,因为百度地图一般是获取当前的地址,我们需要的是他的家庭地址  所以才有了三级Spinner解决 地区问题  就是当用户填写了之后,下次再修改,你要给他显示出来上次填写的值, ...

  9. java页面的模糊查询_利用java8 steam实现代码中模糊搜索以及分页实现

    实现目标 image.png 朋友让实现在后台代码中实现模糊查询; 上代码 public class demoTest { List userzList = Lists.list( new Userz ...

最新文章

  1. SpringCloud中Hystrix容错保护原理及配置,看它就够了!
  2. python【数据结构与算法】内置函数enumerate(枚举) 函数(看不懂你来打我)
  3. ArrayList各方法的时间复杂度
  4. 如何化身BAT面试收割机?不愧是大佬
  5. 请详细描述LVS DR模式的原理
  6. java 群发求职邮件
  7. Java多线程系列--【JUC集合10】- ConcurrentLinkedQueue
  8. 李宏毅2022机器学习HW4解析
  9. iOS-ERROR ITMS-90096
  10. matlab 狄利克雷函数代码,狄利克雷函数
  11. untiy virtual reality supported勾选
  12. 华三交换机 RRPP V7版本
  13. 计组-booth乘法-谈原理和实现
  14. CSS做个五颜六色的风车
  15. 腾讯开源的标星 12k 的力作
  16. 其他笔记-Pycharm必备插件推荐
  17. 实验八 数据处理与多项式处理(matlab)
  18. 打开pix4d无有效许可_PIX4D无人机航拍测量软件mapper pro
  19. 大数据量的兴趣点如何在Cesium快速加载?(weixin公众号【图说GIS】)
  20. Win7系统服务优化完全攻略

热门文章

  1. iOS中 支付宝钱包详解/第三方支付 韩俊强的博客
  2. SUSE Linux ntp 升级报错(MAKE [1]:*** 【all】Error 2)
  3. Linux远程拷贝下载文件
  4. 编程将 .Net Assembly 里的类注册成 COM 类
  5. cube sdio fatfs 初始化sd卡_Stm32CubeMx配置SDIO+FATFS+FREERTOS
  6. 网络设备Web登录检测工具device-phamer
  7. 磁盘镜像工具Guymager
  8. FMDB支持的事务类型
  9. Xamarin.Forms的相对布局RelativeLayout
  10. Xamarin.Form的Android SDK工具下载安装