当模板方法遇到了委托函数,你的代码又能够精简了

现现在当你翻看一些开源项目源码的时候,你会发现如今处处充斥着委托函数,如Func,Action,Predicate,确实如今的C#在函数式编程 的路上愈来愈成为主流,愈来愈显示威力,曾经的一些经典设计模式写法,在函数式下能够稍微优化一下了,这篇咱们就来讲说模板方法。算法

一:实际场景

1. 模板方法定义编程

相信这个模式在平时开发中会常常使用到,定义也很简单,在父类中定义算法骨架,骨架里面的某些细节点由相应的子类实现。设计模式

2. 业务场景编程语言

给用户推送彩信的时候,公司须要对接不少的彩信服务商,好比说博士通,助通,联合维拓,而每一家对提交彩信的格式有不一样的要求, 好比说:博士通和助通会要求全部的内容按指定格式进行base64编码提交过去,联合维拓会要求你按指定格式打包成一个zip文件流过去, 这就是一个经典的模板模式,能够在父类中定义好构造彩信的算法骨架,具体细节能够由各自厂家子类实现,为了方便演示画图以下:ide

当模板方法遇到了委托函数,你的代码又能够精简了

源码以下:函数式编程

class MmsTemplate
{
    public virtual string GetHeader() { return string.Empty; }
    public virtual string GetBody() { return string.Empty; }
    public virtual string GetTail() { return string.Empty; }

    public virtual void Proce***equest()
    {
        Console.WriteLine($"1. 彩信头:{GetHeader()}");
        Console.WriteLine($"2. 彩信体:{GetBody()}");
        Console.WriteLine($"3. 彩信尾:{GetTail()}");
    }
}

class ZhutongTemplate : MmsTemplate
{
    public override string GetHeader() { return "我是助通头!"; }

    public override string GetTail() { return "我是助通体!"; }

    public override string GetBody() { return "我是助通尾!"; }

    public override void Proce***equest() { base.Proce***equest(); }
}

class LianheweituoTemplate : MmsTemplate
{
    public override string GetHeader() { return "我是联合维拓头!"; }

    public override string GetTail() { return "我是联合维拓体!"; }

    public override string GetBody() { return "我是联合维拓尾!"; }

    public override void Proce***equest() { base.Proce***equest(); }
}

而后客户端能够根据指定通道配置调用相应的子类实现不一样厂家的彩信体构建。函数

当模板方法遇到了委托函数,你的代码又能够精简了

二:委托函数

1. 反思优化

在面向对象编程语言中,这种写法都堪称标准,咱们先来捋一下流程,子类入口 -> 执行父类方法 -> 调用子类方法 以下图
当模板方法遇到了委托函数,你的代码又能够精简了this

从上图中能够发现一个问题,父类在执行算法骨架的时候,为了可以再次执行到该子类方法,在面向对象编程中必需要使用的技术就是多态,而为了构造多态,就必须在父类中定义一堆方法,而后由子类实现这一堆方法,这就是你看到的GetHeader(),GetTail(),GetBody()的由来,这时就显得有点老态龙钟。编码

2. 回调函数

仔细看一下这个xmind图,ZhutongTemplate类调用的MmsTemplate的方法,MmsTemplate在执行的时候再调用ZhutongTemplate的方法,前者叫调用,后者叫回调,若是还不明白,那前者叫送礼,后者叫回礼。。。对,既然在之前是用多态制造回调,那我是否是能够直接使用C#中的委托函数更简单粗暴呢?

3. 改造模板

直接看代码吧,千言难抵上代码。

class MmsTemplate
{
    protected Func<string> header;
    protected Func<string> body;
    protected Func<string> tail;

    public virtual void Proce***equest()
    {
        Console.WriteLine($"1. 彩信头:{header()}");
        Console.WriteLine($"2. 彩信体:{header()}");
        Console.WriteLine($"3. 彩信尾:{tail()}");
    }
}

class ZhutongTemplate : MmsTemplate
{
    public override void Proce***equest()
    {
        this.header = () => "我是助通头!";
        this.body = () => "我是助通体";
        this.tail = () => "我是助通尾!";

        base.Proce***equest();
    }
}

class LianheweituoTemplate : MmsTemplate
{
    public override void Proce***equest()
    {
        this.header = () => "我是联合维拓头!";
        this.body = () => "我是联合维拓体";
        this.tail = () => "我是联合维拓尾!";

        base.Proce***equest();
    }
}

从上面代码中能够看到,原来须要多态实现的地方直接由委托变量接管,看起来是否是比以前的多态版简洁了不少。

好了,本篇就说到这里,更多的变通玩法期待您的发现~

相关文章
相关标签/搜索