利用流水线改进代码中的if处理流程
本文用到的编程语言为C#,具体思路不限制编程语言。
刚才正在浏览http://ruby-china.org/topics/7384的时候,看到5楼的回复,突然有一种想法,不知道优劣,请大家帮忙评判一下,或者给出一些更好的实现方案。
我们先来上一段代码,就是常见的一种代码。
- Order getOrder(string orderNo)
- {
- order = repo.getOrder(orderNo);
- if(order.condition1)
- {
- ...
- }
- if(order.condition2)
- {
- ...
- }
- if(order.condition3)
- {
- ...
- }
- .
- .
- .
- }
上面是一段伪代码,实现的就是一个根据订单号,获取订单,然后根据订单的一些条件进行一些处理。
order是获取出来的订单,condition1、condition2、condition3是一些条件。随着业务的复杂,condition3后面还可能更多的condition,就需要添加更多的if,进行更多的判断,然后这个方法越来越长,越来越难以读懂,越来越难以维护,越来越。。。
我想是不是可以换个角度,不是订单来判断条件,然后执行一些代码。而是订单进入一个处理流程,然后处理流程中有很多的闸门,每个闸门代表一个特征条件处理器,然后由这个处理器来判断流经自己的订单是否符合条件,符合就处理,不符合就掠过。
这样有几个好处:
- 上面代码中的获取订单方法,不会越来越长,这样阅读起来就很好理解,在后面进行维护的时候,就很容易来做了。
- 添加一个新的条件处理分支也很容易,只要把这种条件处理看做是一个闸门,在处理流水线中加入新闸门就可以了,其他的都不需要变化。
- 调整原来的条件处理,也只需要修改闸门内部的处理代码即可,不用担心是否影响其他处理分支。
- 分支独立之后,还可以针对每个分支做单元测试。
其实扩展开来想,这个流程不仅可以处理订单,任何针对一个对象进行流程化处理的场景,都可以套用上面的代码结构,都可以得到上面的好处。
我画了一个示意图。
图 1.1 对象处理流水线
放出一段示例代码。
- public interface IRepo
- {
- string getOrder(string orderNo);
- }
- public class Repo : IRepo
- {
- public string getOrder(string orderNo)
- {
- return string.Empty;
- }
- }
- public class Client
- {
- public void getOrder(string orderNo)
- {
- var order = new Repo().getOrder(orderNo);
- var pipeline = new Pipeline();
- var handle1 = new condition1_Handle();
- var handle2 = new condition2_Handle();
- pipeline.add_order(order);
- pipeline.add_handle(handle1);
- pipeline.add_handle(handle2);
- pipeline.processOrder();
- }
- }
- class Pipeline
- {
- private List<IHandle> _handles;
- private string _order;
- public Pipeline()
- { _handles = new List<IHandle>(); }
- internal void add_order(string order)
- {
- this._order = order;
- }
- internal void add_handle(IHandle handle1)
- {
- _handles.Add(handle1);
- }
- internal void processOrder()
- {
- foreach (var h in _handles)
- {
- h.process(_order);
- }
- }
- }
- public interface IHandle
- {
- void process(string order);
- }
- public class condition1_Handle : IHandle
- {
- public void process(string _order)
- {
- throw new NotImplementedException();
- }
- }
- public class condition2_Handle : IHandle
- {
- public void process(string _order)
- {
- throw new NotImplementedException();
- }
- }
感觉有点像是策略模式,但是感觉又不太像。
上面的代码还有优化的空间,大家有没有更好的方案呢,欢迎大家一起讨论!
稍加改进,引入泛型,就可以支持任意类型的对象处理。
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace ConsoleClient.Pipeline
- {
- public interface IRepo
- {
- Purchase getOrder(string orderNo);
- Product getProduct(int id);
- }
- public class Repo : IRepo
- {
- public Purchase getOrder(string orderNo)
- {
- return new Purchase();
- }
- public Product getProduct(int id)
- {
- return new Product();
- }
- }
- public class Client
- {
- public Purchase getOrder(string orderNo)
- {
- var order = new Repo().getOrder(orderNo);
- var pipeline = new Pipeline<Purchase>();
- var handle1 = new condition1_orderHandle();
- var handle2 = new condition2_orderHandle();
- pipeline.add_order(order);
- pipeline.add_handle(handle1);
- pipeline.add_handle(handle2);
- pipeline.processOrder();
- return order;
- }
- public Product getProduct(int id)
- {
- var product = new Repo().getProduct(id);
- var pipeline = new Pipeline<Product>();
- var handle1 = new condition1_productHandle();
- var handle2 = new condition2_productHandle();
- pipeline.add_order(product);
- pipeline.add_handle(handle1);
- pipeline.add_handle(handle2);
- pipeline.processOrder();
- return product;
- }
- }
- public class Pipeline<T>
- {
- private List<IHandle<T>> _handles;
- private T _order;
- public Pipeline()
- { _handles = new List<IHandle<T>>(); }
- public void add_order(T order)
- {
- this._order = order;
- }
- public void add_handle(IHandle<T> handle1)
- {
- _handles.Add(handle1);
- }
- public void processOrder()
- {
- foreach (var h in _handles)
- {
- h.process(_order);
- }
- }
- }
- public class Purchase
- {
- public bool IsPay { get; set; }
- }
- public class Product
- {
- public bool IsExpired { get; set; }
- }
- public interface IHandle<T>
- {
- void process(T order);
- }
- public class condition1_orderHandle : IHandle<Purchase>
- {
- public void process(Purchase order)
- {
- if (order.IsPay == false )
- {
- Console.WriteLine("you don't pay money");
- }
- }
- }
- public class condition2_orderHandle : IHandle<Purchase>
- {
- public void process(Purchase order)
- {
- }
- }
- public class condition1_productHandle : IHandle<Product>
- {
- public void process(Product product)
- {
- }
- }
- public class condition2_productHandle : IHandle<Product>
- {
- public void process(Product product)
- {
- }
- }
- }
本文转自 virusswb 51CTO博客,原文链接:http://blog.51cto.com/virusswb/1081790,如需转载请自行联系原作者
利用流水线改进代码中的if处理流程相关推荐
- jeeplus代码中配置并开发流程
需求 流程绘制 一.配置流程 在流程工具类ActUtils.java中配置(添加)流程信息 二.在前台leaveList页面添加使用流程的触发事件(提交按钮) 三.编写代码[本文仅针对流程(提交事件) ...
- python代码物理_利用python求解物理学中的双弹簧质能系统详解
前言 本文主要给大家介绍了关于利用python求解物理学中双弹簧质能系统的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 物理的模型如下: 在这个系统里有两个物体,它们的质 ...
- python对excel数据更改_利用python对excel中一列的时间数据更改格式代码示例
本篇文章小编给大家分享一下利用python对excel中一列的时间数据更改格式代码示例,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. 问题场景:需要将 ...
- 自检代码中trustmanager漏洞_Windows内核漏洞利用教程
堆栈溢出漏洞 首先,我们将从HackSysExtremeVulnerableDriver中的vanilla栈溢出漏洞开始讲起. 当向堆栈上的缓冲区存放的数据超出其存储容量时(例如,向16字节缓冲区(这 ...
- html天气插件iframe,HTML_利用iframe在网页中显示天气附效果截图,css: 复制代码代码如下: *{margi - phpStudy...
利用iframe在网页中显示天气附效果截图 css: 复制代码代码如下: *{margin:0;padding:0;list-style-type:none;} a,img{border:0;} bo ...
- Unity 在代码中利用Mesh实时生成圆环/空心圆柱
本篇文章主要介绍了利用Unity中的mesh 实时生成圆环的过程以及思想,我会在开头直接放出源码.如若有任何疑问,可向后继续观看详细解说~~~ (PSPSPS:Mesh生成的顺序,方式等有很多,当前代 ...
- C语言系列(二):最近重拾C语言的想法,谈到C中易错点,难点;以及开源代码中C语言的一些常用技巧,以及如何利用define、typedef、const等写健壮的C程序...
写在前面的话:本系列主要是自己在c语言运用时,对一些不了解,但开源代码中常用的技巧,和一些c语言中偏门和易错点进行解析. 加入了自己的分析,如果不到位请多海涵,另外,引用一些非常好的文章(都有引用li ...
- android在代码中利用Spinner控件设置联动地区的解决办法
需求就是地区选择可以弹出来,因为百度地图一般是获取当前的地址,我们需要的是他的家庭地址 所以才有了三级Spinner解决 地区问题 就是当用户填写了之后,下次再修改,你要给他显示出来上次填写的值, ...
- java页面的模糊查询_利用java8 steam实现代码中模糊搜索以及分页实现
实现目标 image.png 朋友让实现在后台代码中实现模糊查询; 上代码 public class demoTest { List userzList = Lists.list( new Userz ...
最新文章
- SpringCloud中Hystrix容错保护原理及配置,看它就够了!
- python【数据结构与算法】内置函数enumerate(枚举) 函数(看不懂你来打我)
- ArrayList各方法的时间复杂度
- 如何化身BAT面试收割机?不愧是大佬
- 请详细描述LVS DR模式的原理
- java 群发求职邮件
- Java多线程系列--【JUC集合10】- ConcurrentLinkedQueue
- 李宏毅2022机器学习HW4解析
- iOS-ERROR ITMS-90096
- matlab 狄利克雷函数代码,狄利克雷函数
- untiy virtual reality supported勾选
- 华三交换机 RRPP V7版本
- 计组-booth乘法-谈原理和实现
- CSS做个五颜六色的风车
- 腾讯开源的标星 12k 的力作
- 其他笔记-Pycharm必备插件推荐
- 实验八 数据处理与多项式处理(matlab)
- 打开pix4d无有效许可_PIX4D无人机航拍测量软件mapper pro
- 大数据量的兴趣点如何在Cesium快速加载?(weixin公众号【图说GIS】)
- Win7系统服务优化完全攻略
热门文章
- iOS中 支付宝钱包详解/第三方支付 韩俊强的博客
- SUSE Linux ntp 升级报错(MAKE [1]:*** 【all】Error 2)
- Linux远程拷贝下载文件
- 编程将 .Net Assembly 里的类注册成 COM 类
- cube sdio fatfs 初始化sd卡_Stm32CubeMx配置SDIO+FATFS+FREERTOS
- 网络设备Web登录检测工具device-phamer
- 磁盘镜像工具Guymager
- FMDB支持的事务类型
- Xamarin.Forms的相对布局RelativeLayout
- Xamarin.Form的Android SDK工具下载安装