zoukankan      html  css  js  c++  java
  • 封装业务函数

    链式调用 - 封装业务函数

    用设计模式、AOP能将一个方法/函数包裹起来,并且插入额外的逻辑行为,不过动作比较大,不是很灵活,下面介绍一种链式调用方法来封装的代码,完成后能实现如下的链式调用:

    复制代码
    public class BO
            {
                public bool Add(string msg)
                {
                    Console.WriteLine("Add");
    
                    if (msg == null)
                        throw new Exception();
    
                    return true;
                }
            }
    
            static void Main(string[] args)
            {
                BO bo=new BO();
    
                Pipeline<string, bool> p = Pipeline.Wrap<string, bool>(bo.Add)
                            .BeforeExecute(m=>Console.WriteLine("before execute"))
                            .AfterExecute((m, n) => Console.WriteLine("after execute1"))
                            .AfterExecute((m, n) => Console.WriteLine("after execute2"))
                            .Success((m, n) => Console.WriteLine("success"))
                            .Fail((m, n) => Console.WriteLine("fail"))
                            .Final((m, n) => Console.WriteLine("final"));
    
    
                Console.WriteLine("Result: "+p.Execute("testing").Result);
    
                Console.WriteLine();
                Console.WriteLine();
    
                Console.WriteLine("Result: " + p.Execute(null).Result);
    
                Console.ReadKey();
            }
    复制代码

     运行图:

     注意:这个封装会对目标业务函数加入try/catch来得到业务是否成功执行。

    实现起来比较简单,就是每个函数返回自身,如下:

    复制代码
    public static class Pipeline//这里只实现了2个泛型,可以增加很多个(这点比较麻烦)
        {
            public static Pipeline<TIN, TOUT> Wrap<TIN, TOUT>(Func<TIN, TOUT> method)
            {
                Pipeline<TIN, TOUT> p = new Pipeline<TIN, TOUT>(method);
                return p;
            }
    
            public static Pipeline<TIN1, TIN2, TOUT> Wrap<TIN1, TIN2, TOUT>(Func<TIN1, TIN2, TOUT> method)
            {
                Pipeline<TIN1, TIN2, TOUT> p = new Pipeline<TIN1, TIN2, TOUT>(method);
                return p;
            }
        }
    复制代码

     最终返回的结果对象:

    复制代码
    public struct PipelineResult<TOUT>
        {
            /// <summary>
            /// 目标核心函数返回值
            /// </summary>
            public TOUT Result { get; set; }
    
            /// <summary>
            /// 是否存在异常
            /// </summary>
            public bool ExceptionExists { get; set; }
    
            /// <summary>
            /// 具体的异常
            /// </summary>
            public Exception Exception { get; set; }
        }
    复制代码

     只有一个输入参数的Wrapper:

    复制代码
    public class Pipeline<TIN, TOUT>
        {
            private Func<TIN, TOUT> method2Execute;
            private List<Action<TIN>> beforeExecuteActions = new List<Action<TIN>>();
            private List<Action<TIN, TOUT>> afterExecuteActions = new List<Action<TIN, TOUT>>();
            private Action<TIN, TOUT> finalAction;
            private List<Action<TIN, TOUT>> successActions = new List<Action<TIN, TOUT>>();
            private List<Action<TIN, TOUT>> failActions = new List<Action<TIN, TOUT>>();
    
            public Pipeline(Func<TIN, TOUT> method)
            {
                this.method2Execute = method;
            }
    
            public Pipeline<TIN, TOUT> BeforeExecute(Action<TIN> action)
            {
                beforeExecuteActions.Add(action);
    
                return this;
            }
    
            public Pipeline<TIN, TOUT> AfterExecute(Action<TIN, TOUT> action)
            {
                afterExecuteActions.Add(action);
    
                return this;
            }
    
            public Pipeline<TIN, TOUT> Final(Action<TIN, TOUT> action)
            {
                this.finalAction = action;
    
                return this;
            }
    
            public Pipeline<TIN, TOUT> Success(Action<TIN, TOUT> action)
            {
                successActions.Add(action);
    
                return this;
            }
    
            public Pipeline<TIN, TOUT> Fail(Action<TIN, TOUT> action)
            {
                failActions.Add(action);
    
                return this;
            }
    
            public PipelineResult<TOUT> Execute(TIN argument)
            {
                PipelineResult<TOUT> result = new PipelineResult<TOUT>();
    
                foreach (var action in this.beforeExecuteActions)
                    action.Invoke(argument);
    
                try
                {
                    result.Result = this.method2Execute.Invoke(argument);
                    result.ExceptionExists = false;
                    result.Exception = null;
                }
                catch (Exception ex)
                {
                    result.ExceptionExists = true;
                    result.Exception = ex;
                }
    
                foreach (var action in this.afterExecuteActions)
                    action.Invoke(argument, result.Result);
    
                if (!result.ExceptionExists)
                {
                    foreach (var action in this.successActions)
                        action.Invoke(argument, result.Result);
                }
                else
                {
                    foreach (var action in this.failActions)
                        action.Invoke(argument, result.Result);
                }
    
                if (this.finalAction != null)
                    this.finalAction.Invoke(argument, result.Result);
    
                return result;
            }
        }
    复制代码

    支持2个输入参数的Wrapper:

    复制代码
    public class Pipeline<TIN1, TIN2, TOUT>
        {
            private Func<TIN1, TIN2, TOUT> method2Execute;
            private List<Action<TIN1, TIN2>> beforeExecuteActions = new List<Action<TIN1, TIN2>>();
            private List<Action<TIN1, TIN2, TOUT>> afterExecuteActions = new List<Action<TIN1, TIN2, TOUT>>();
            private Action<TIN1, TIN2, TOUT> finalAction;
            private List<Action<TIN1, TIN2, TOUT>> successActions = new List<Action<TIN1, TIN2, TOUT>>();
            private List<Action<TIN1, TIN2, TOUT>> failActions = new List<Action<TIN1, TIN2, TOUT>>();
    
            public Pipeline(Func<TIN1, TIN2, TOUT> method)
            {
                this.method2Execute = method;
            }
    
            public Pipeline<TIN1, TIN2, TOUT> BeforeExecute(Action<TIN1, TIN2> action)
            {
                beforeExecuteActions.Add(action);
    
                return this;
            }
    
            public Pipeline<TIN1, TIN2, TOUT> AfterExecute(Action<TIN1, TIN2, TOUT> action)
            {
                afterExecuteActions.Add(action);
    
                return this;
            }
    
            public Pipeline<TIN1, TIN2, TOUT> Final(Action<TIN1, TIN2, TOUT> action)
            {
                this.finalAction = action;
    
                return this;
            }
    
            public Pipeline<TIN1, TIN2, TOUT> Success(Action<TIN1, TIN2, TOUT> action)
            {
                successActions.Add(action);
    
                return this;
            }
    
            public Pipeline<TIN1, TIN2, TOUT> Fail(Action<TIN1, TIN2, TOUT> action)
            {
                failActions.Add(action);
    
                return this;
            }
    
            public PipelineResult<TOUT> Execute(TIN1 argument1, TIN2 argument2)
            {
                PipelineResult<TOUT> result = new PipelineResult<TOUT>();
    
                foreach (var action in this.beforeExecuteActions)
                    action.Invoke(argument1, argument2);
    
                try
                {
                    result.Result = this.method2Execute.Invoke(argument1, argument2);
                    result.ExceptionExists = false;
                    result.Exception = null;
                }
                catch (Exception ex)
                {
                    result.ExceptionExists = true;
                    result.Exception = ex;
                }
    
                foreach (var action in this.afterExecuteActions)
                    action.Invoke(argument1, argument2, result.Result);
    
                if (!result.ExceptionExists)
                {
                    foreach (var action in this.successActions)
                        action.Invoke(argument1, argument2, result.Result);
                }
                else
                {
                    foreach (var action in this.failActions)
                        action.Invoke(argument1, argument2, result.Result);
                }
    
                if (this.finalAction != null)
                    this.finalAction.Invoke(argument1, argument2, result.Result);
    
                return result;
            }
        }
    复制代码

    支持更多输入参数的?不要返回值的?自己搞定吧。 

    尽管这个模式很简单,但是只要扩展一下,就能做简单的复合业务逻辑,比如xml文件来配置,最终组合成复合业务,很有潜力的一个模式。 

     

    自省推动进步,视野决定未来。
    心怀远大理想。
    为了家庭幸福而努力。
    A2D科技,服务社会。
    A2D Framework(Alpha)
    • 1. Cache System(本地缓存与分布式缓存共存、支持Memcache和Redis、支持贴标签形式(类似Spring 3.x的Cache形式))
    • 2. Event System(本地事件与分布式事件分发)
    • 3. IoC(自动匹配功能,实例数量限制功能)
    • 4. Sql Dispatcher System(支持ADO.NET及EF)
    • 5. Session System(分布式Session系统)
    • 6. 分布式Command Bus(MSMQ实现,解决4M限制,支持Session的读取)
    • 7. 规则引擎

    QQ群:283016070,真材实料的.NET架构师

     

     

     

  • 相关阅读:
    Spring 缓存抽象
    Nginx配置入门
    CSS 小结笔记之解决flex布局边框对不齐
    CSS 小结笔记之图标字体(IconFont)
    CSS 小结笔记之em
    CSS 小结笔记之BFC
    CSS 实例之滚动的图片栏
    CSS 实例之翻转图片
    CSS 实例之打开大门
    CSS 小结笔记之伸缩布局 (flex)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3627148.html
Copyright © 2011-2022 走看看