Template Method Design Pattern in Delphi

Applications in Delphi

Abstraction is implemented in Delphi by abstract virtual methods. Abstract methods differ from virtual methods by the base class not providing any implementation. The descendant class is completely responsible for implementing an abstract method. Calling an abstract method that has not been overridden will result in a runtime error.

A typical example of abstraction is the TGraphic class.

TGraphic is an abstract class used to implement TBitmap, TIcon and TMetafile. Other developers have frequently used TGraphic as the basis for other graphics objects such as PCX, GIF, JPG representations. TGraphic defines abstract methods such as Draw, LoadFromFile and SaveToFile which are then overridden in the concrete classes. Other objects that use TGraphic, such as a TCanvas only know about the abstract Draw method, yet are used with the concrete class at runtime.

Many classes that use complex algorithms are likely to benefit from abstraction using the template method approach. Typical examples include data compression, encryption and advanced graphics processing.

Implementation Example

To implement template methods you need an abstract class and concrete classes for each alternate implementation. Define a public interface to an algorithm in an abstract base class. In that public method, implement the steps of the algorithm in calls to protected abstract methods of the class. In concrete classes derived from the base class, override each step of the algorithm with a concrete implementation specific to that class.

This example shows some very simple algorithm steps, but illustrates the principle of deferring implementation to a subclass.

unit Tpl_meth;

interface

type

  TAbstractTemplateClass = class(TObject)
  protected
    function Algorithm_StepA: Integer; virtual; abstract;
    function Algorithm_StepB: Integer; virtual; abstract;
    function Algorithm_StepC: Integer; virtual; abstract;
  public
    function Algorithm: Integer;
  end;

  TConcreteClassA = class(TAbstractTemplateClass)
  protected
    function Algorithm_StepA: Integer; override;
    function Algorithm_StepB: Integer; override;
    function Algorithm_StepC: Integer; override;
  end;
 
  TConcreteClassB = class(TAbstractTemplateClass)
  protected
    function Algorithm_StepA: Integer; override;
    function Algorithm_StepB: Integer; override;
    function Algorithm_StepC: Integer; override;
  end;

  ...

Code examples