本文用到的编程语言为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,如需转载请自行联系原作者