When the template method encounters a delegate function, your code can be simplified again

Time:2020-11-27

Now when you look at the source code of some open source projects, you will find that delegate functions, such as func, action, predict, are everywhere now. Indeed, C ᦇ is in functional programming
On the way to become more and more mainstream, more and more power, once some of the classic design pattern writing, in the function can be slightly optimized, this article will talk about template method.

1: Actual scenario

1. Definition of template method

It is believed that this pattern is often used in development and its definition is very simple. The algorithm skeleton is defined in the parent class, and some details in the skeleton are implemented by corresponding subclasses.

2. Business scenarios

When pushing MMS to users, the company needs to connect with many MMS service providers, such as Bostone, Hutong and univito. Each company has different requirements on the format of MMS submission,
For example, Bostone and Hutong require all content to be Base64 encoded and submitted in the specified format. Univito requires you to package it into a zip file stream in the specified format,
This is a classic template mode. The algorithm skeleton of MMS can be defined in the parent class. The details can be implemented by the subclass of each manufacturer. For the convenience of demonstration, the drawing is as follows:

When the template method encounters a delegate function, your code can be simplified again

The source code is as follows:

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 ProcessRequest()
        {
            Console.WriteLine ($"1. MMS header: {getheader()}");
            Console.WriteLine ($"2. MMS: {getbody()}");
            Console.WriteLine ($"3. End of MMS: {gettail()}");
        }
    }

    class ZhutongTemplate : MmsTemplate
    {
        Public override string getheader() {return "I'm a helper! "; }

        Public override string gettail() {return "I am a general helper! "; }

        Public override string getbody() {return "I'm a helper! "; }

        public override void ProcessRequest() { base.ProcessRequest(); }
    }

    class LianheweituoTemplate : MmsTemplate
    {
        Public override string getheader() {return "I'm a joint Vito head! "; }

        Public override string gettail() {return "I am a union dimension! "; }

        Public override string getbody() {return "I'm a united dimension tail! "; }

        public override void ProcessRequest() { base.ProcessRequest(); }
    }

Then the client can call the corresponding subclass according to the specified channel configuration to realize the construction of MMS from different manufacturers.

When the template method encounters a delegate function, your code can be simplified again

2: Delegate function

1. Reflection

In an object-oriented programming language, this is a standard. Let’s take a look at the flow,Subclass entry > execute parent method > call subclass methodAs shown in the figure below

When the template method encounters a delegate function, your code can be simplified again

A problem can be found from the above figure. When the parent class executes the algorithm skeleton, in order to be able to execute the subclass method again, the technology that must be used in object-oriented programming is polymorphism. In order to construct polymorphism, you must define a bunch of methods in the parent class, and then the child class implements this heap of methods. This is getheader(), gettail(), The origin of getbody() seems a bit old-fashioned at this time.

2. Callback function

Take a closer look at the XMIND diagram. The mmtemplate method called by the zhutongtemplate class will call the zhutongtemplate method when it is executed. The former is called call back, and the latter is called callback. If you don’t understand, the former is called gift giving and the latter is called return gift… Yes, since I used to make callbacks with polymorphism, can I use the delegate function in C ා, which is simpler and more crude?

3. Transformation of formwork

Look directly at the code, a thousand words is not worth the code.

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

        public virtual void ProcessRequest()
        {
            Console.WriteLine ($"1. MMS header: {header()}");
            Console.WriteLine ($"2. MMS: {header()}");
            Console.WriteLine ($"3. End of MMS: {tail()}");
        }
    }

    class ZhutongTemplate : MmsTemplate
    {
        public override void ProcessRequest()
        {
            this.header  =() = > "I'm a helper! ";
            this.body  =() = > "I am the Tongti";
            this.tail  =() = > "I am the assistant Tongwei! ";

            base.ProcessRequest();
        }
    }

    class LianheweituoTemplate : MmsTemplate
    {
        public override void ProcessRequest()
        {
            this.header  =() = > "I am the head of United Vito! ";
            this.body  =() = > "I am a joint dimension body";
            this.tail  =() = > "I am the United Vito tail! ";

            base.ProcessRequest();
        }
    }

From the above code, we can see that the original need for polymorphic implementation is directly taken over by the delegate variable. It seems that it is much simpler than the previous polymorphic version.

Well, that’s all for this article. I’m looking forward to your discovery of more flexible games~