Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the use of Template Method in Base Classes?

Well, I was going through this excellent article on MSDN about "Base Class Usage". While I understand the concept of base class and interfaces, I am unable to comprehend the usage of Template methods in the second paragraph of this article ("Protected Methods and Constructors").

Could anyone help me to understand this concept with the help of a simple practical example? Perhaps, understanding the concept of Template Method is a good place to start.

Thanks in advance.

like image 307
Aakash Avatar asked Oct 22 '22 17:10

Aakash


2 Answers

That is very old article in my opinion, don't remember seeing naming with Impl.

I think wikipedia has better description:
The template method is used to:

  • let subclasses implement (through method overriding) behavior that can vary

  • avoid duplication in the code: the general workflow structure is implemented once in the abstract class's algorithm, and necessary variations are implemented in each of the subclasses.

  • control at what point(s) subclassing is allowed. As opposed to a simple polymorphic override, where the base method would be entirely rewritten allowing radical change to the workflow, only the specific details of the workflow are allowed to change.

The control structure (inversion of control) that is the result of the application of a template pattern is often referred to as the Hollywood Principle: "Don't call us, we'll call you." Using this principle, the template method in a parent class controls the overall process by calling subclass methods as required.

In simple words, you define skeleton in your base class, and derived classes implement differences between implementations.

Let's say we have information, that must be published to different channels.
So we make base class Publisher, that has skeleton how to do that.
We force to implement initialization, that every derive would set address where to publish.
We make sending implementation, that fits most of the channels and if some channel uses ftp instead of http, we let to override sending.
And logging to dababase what was done is the same for all channels, so we don't let to override that.
Only publishing is interesing to user of Publisher derrived class, so only that method is public.

public abstract class Publisher 
{
      private address;
      // if you wish to force implementation in derived class, make method abstract
      private abstract void Initialize();
      // if you wish optional implementation in derived class, make it virtual
      protected virtual void SendChangesToWeb() 
      {
         // ...
         webClient.Upload(address, data)
      }

      // if you wish that some step could not be changed from outside 
      private void LogSentChangesToDatabase() 
      {
         // ... save date time when was send and what was sent
      }

      // this sequence is the same for all derives, no point to duplicate 
      public void PublishUpdates() 
      {
           Initialize();
           SendChangesToWeb();
           LogSentChangesToDatabase();
      }
}

public class GooglePublisher : Publisher {
     private override Initialize() 
     {
         address = "http://www.google.com";
     }         
}

public class FtpPublisher : Publisher {
     private override Initialize() 
     {
         address = "ftp://test.com";
     }     

     protected override SendChangesToWeb() 
     {
        FtpClient.Upload(address, data)
     }
}
like image 75
Giedrius Avatar answered Oct 31 '22 12:10

Giedrius


The idea is that you have multiple public overloads of a method that all internally use a single method. So none of the public overloads has the implementation itself. Instead a protected method is used for the actual implementation of all the overloads.

So first of all, you don’t repeat yourself, as you only have the implementation once and all overloads with defaults simply call the implementation by setting some default values.

Now when inheriting the class, the deriving class can simply override the internal implementation once and all previously public overloads will immediately use the new implementation. So you can specify the public interface in the base class with a standard implementation but allow deriving classes to change that implementation while abiding to the interface contract.

Now one could argue why the implementation is put in a separate method, and I seriously don’t know. Instead one could easily implement the most generic signature of a method and simply make the other methods call that one instead of an internal one. A reason for a separate method might be that you could add internal usage parameters that are not visible to the public methods, but I guess that depends on what you want to do.

like image 39
poke Avatar answered Oct 31 '22 12:10

poke