Question

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.

Was it helpful?

Solution

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)
     }
}

OTHER TIPS

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.

You can search for Template Method Design Pattern. This pattern includes a Template method, which provides a skeleton calling sequence of methods. One or more steps can be deferred to subclasses which implement these steps without changing the overall calling sequence. Example:

// Template Method pattern -- Structural example

using System;



namespace DoFactory.GangOfFour.Template.Structural

{

  /// <summary>

  /// MainApp startup class for Real-World

      /// Template Design Pattern.

      /// </summary>

      class MainApp

  {

    /// <summary>

    /// Entry point into console application.

    /// </summary>

    static void Main()

    {

      AbstractClass aA = new ConcreteClassA();

      aA.TemplateMethod();



      AbstractClass aB = new ConcreteClassB();

      aB.TemplateMethod();



      // Wait for user

      Console.ReadKey();

    }

  }



  /// <summary>

  /// The 'AbstractClass' abstract class

  /// </summary>

  abstract class AbstractClass

  {

    public abstract void PrimitiveOperation1();

    public abstract void PrimitiveOperation2();



    // The "Template method"

    public void TemplateMethod()

    {

      PrimitiveOperation1();

      PrimitiveOperation2();

      Console.WriteLine("");

    }

  }



  /// <summary>

  /// A 'ConcreteClass' class

  /// </summary>

  class ConcreteClassA : AbstractClass

  {

    public override void PrimitiveOperation1()

    {

      Console.WriteLine("ConcreteClassA.PrimitiveOperation1()");

    }

    public override void PrimitiveOperation2()

    {

      Console.WriteLine("ConcreteClassA.PrimitiveOperation2()");

    }

  }



  /// <summary>

  /// A 'ConcreteClass' class

  /// </summary>

  class ConcreteClassB : AbstractClass

  {

    public override void PrimitiveOperation1()

    {

      Console.WriteLine("ConcreteClassB.PrimitiveOperation1()");

    }

    public override void PrimitiveOperation2()

    {

      Console.WriteLine("ConcreteClassB.PrimitiveOperation2()");

    }

  }

}

Reference : Template Method Design Pattern

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top