Template Method Design Pattern in Delphi. A working example

The Template Method Pattern is very easy to understand and implement. Here’s the definition borrowed from Design Patterns: Elements of Reusable Object-Oriented Software book:

“Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.”

Let’s try to understand the pattern walking through a simple example. For implementing the solution we’ll use Delphi XE, but it should work for previous versions as well.

This is the wording of the example:

Design an application that allows drawing different styles of houses (ei. country house, city house) using ASCII art [1].

In the following image there’s a prototype of the user interface.
Template Pattern Example (Delphi) – Country House
The GUI is composed by a form, a memo [2], two buttons, a label and a combo box. Using the combo box you can choose whether your house will have a chimney or not. Clicking the buttons will result in an ASCII house printed out in the memo area. In the example above, the Draw Country House was clicked. If you click the other button, you will get city house like the one below:
Template Pattern Example (Delphi) – City House
What happens if you select “No” in the combo box? Try it and let me know :-) Here’s the link to the EXE. This EXE is harmless; I am not a bad guy: no Trojans, no viruses, just Delphi :-)

Now, what classes do we need to make this work? Take a look at the following class diagram and try to make sense of it:
Template Pattern Example (Delphi) – Class diagram
We have an abstract superclass THouse, which contains four abstract (pure virtual) methods: BuildFloor, BuildWalls, BuildRoof and BuildChimney. These methods are implemented in the descending classes TCountryHouse and TCityHouse. Pay special attention to the method BuildIt in THouse. This method is an instance method that is inherited by both concrete subclasses: TCountryHouse and TCityHouse.  

I want to be more detailed:

The BuildIt method is implemented just once in the class THouse. The subclasses TCountryHouse and TCityHouse don’t have to implement the BuildIt method.

The BuildFloor, BuildWalls, BuildRoof and BuildChimney methods have no implementation under the THouse class. The TCountryHouse has one implementation of these methods, while TCityHouse have a different implementation of them.
    
This is how the BuildIt method looks like:

function THouse.BuildIt: string;
begin
  Result:= BuildRoof  +  //Step 1
           BuildWalls +  //Step 2
           BuildFloor;   //Step 3

  if FHasChimney then
    Result:= BuildChimney+ Result;  //Step 4 (conditional)
end;

This method defines a general algorithm to build a house…it doesn’t take into consideration the kind of house that’s been built. Notice that the steps for building the roof, walls, floor and chimney (if any) have been deferred to the subclasses. The BuildIt method is known as a template method that gives the name to this pattern.

Let me give you an idea of the implementation of the BuildFloor method. This method is implemented directly by the subclasses. Take a look:

function TCountryHouse.BuildFloor: string;
begin
  Result:=

  '~~~~~"   "~~~~~~~~~~~~~~~~~~~~~~~~  ';
end;

function TCityHouse.BuildFloor: string;
begin
  Result:=

  '******************____****************'#13#10 +
  '**************************************';
end;

Notice that the implementation of the BuildFloor method is different in both subclasses TCountryHouse and TCityHouse.

For the implementation of the remaining methods refer to reference [5]. For the full source code refer to [3].

In conclusion, the template method pattern needs an abstract superclass to implement a template method (common for all subclasses). The steps within this template method are deferred into methods that are implemented by the concrete subclasses. Did you get it? :-)

Do you want to know more about design patterns? The books in reference [4] are just what you need.

References:

[1] I am borrowing the ASCII designs from Asciiworld.com : House.

[2] Make sure to use a fixed-width font (Courier, Monaco, Courier New, Lucida Console, etc.) for the memo, otherwise the drawing will look fuzzy.

[3] Get the full source code of this example here.

[4] Books on Design Patterns:




[5] The full source code of the unit:

unit TemplatePatternExample;

interface
type
  THouse = class
  private
    FHasChimney: Boolean;
  public
    constructor Create;

    property HasChimney: Boolean read  FHasChimney
                                 write FHasChimney;

    function BuildFloor: string;   virtual; abstract;
    function BuildWalls: string;   virtual; abstract;
    function BuildRoof: string;    virtual; abstract;
    function BuildChimney: string; virtual; abstract;

    function BuildIt: string;
  end;

  TCountryHouse = class(THouse)
  public
    function BuildFloor: string;   override;
    function BuildWalls: string;   override;
    function BuildRoof: string;    override;
    function BuildChimney: string; override;
  end;

  TCityHouse = class(THouse)
  public
    function BuildFloor: string;   override;
    function BuildWalls: string;   override;
    function BuildRoof: string;    override;
    function BuildChimney: string; override;
  end;

implementation

{ THouse }

constructor THouse.Create;
begin
  inherited Create;
  FHasChimney:= True;
end;

function THouse.BuildIt: string;
begin
  Result:= BuildRoof  +  //Step 1
           BuildWalls +  //Step 2
           BuildFloor;   //Step 3

  if FHasChimney then
    Result:= BuildChimney+ Result;  //Step 4 (conditional)
end;

{ TCountryHouse }

function TCountryHouse.BuildChimney: string;
begin
  Result:=

  '              (   )                '#13#10 +
  '             (    )                '#13#10 +
  '              (    )               '#13#10 +
  '             (    )                '#13#10 +
  '               )  )                '#13#10 +
  '              (  (                 '#13#10 +
  '               (_)                 '#13#10 +
  '               [ ]                 '#13#10;
end;

function TCountryHouse.BuildRoof: string;
begin
  Result:=

  '       ___________________       '#13#10 +
  '      /\        ______    \      '#13#10 +
  '     //_\       \    /\    \     '#13#10 +
  '    //___\       \__/  \    \    '#13#10 +
  '   //_____\       \ |[]|     \   '#13#10 +
  '  //_______\       \|__|      \  '#13#10 +
  ' /XXXXXXXXXX\                  \ '#13#10 +
  '/_I_II  I__I_\__________________\'#13#10;
end;

function TCountryHouse.BuildWalls: string;
begin
  Result:=

  '  I_I|  I__I_____[]_|_[]_____I'#13#10 +
  '  I_II  I__I_____[]_|_[]_____I'#13#10 +
  '  I II__I  I     XXXXXXX     I'#13#10;
end;

function TCountryHouse.BuildFloor: string;
begin
  Result:=

  '~~~~~"   "~~~~~~~~~~~~~~~~~~~~~~~~  ';
end;

{ TCityHouse }

function TCityHouse.BuildChimney: string;
begin
  Result:=

  '                           ====  '#13#10 +
  '                           !!!!  '#13#10;
end;

function TCityHouse.BuildRoof: string;
begin
  Result:=

  '      ==========================      '#13#10 +
  '    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    '#13#10 +
  '  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  '#13#10 +
  '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'#13#10;
end;

function TCityHouse.BuildWalls: string;
begin
  Result:=

  '  ||      _____          _____    ||'#13#10 +
  '  ||      | | |          | | |    ||'#13#10 +
  '  ||      |-|-|          |-|-|    ||'#13#10 +
  '  ||      #####          #####    ||'#13#10 +
  '  ||                              ||'#13#10 +
  '  ||      _____   ____   _____    ||'#13#10 +
  '  ||      | | |   @@@@   | | |    ||'#13#10 +
  '  ||      |-|-|   @@@@   |-|-|    ||'#13#10 +
  '  ||      #####   @@*@   #####    ||'#13#10 +
  '  ||              @@@@            ||'#13#10;
end;

function TCityHouse.BuildFloor: string;
begin
  Result:=

  '******************____****************'#13#10 +
  '**************************************';
end;

end.

New certifications available for Delphi Developers

Last June 12th, 2011, I received an Embarcadero Community Newsletter pointing out that “certification exams are now available for Delphi developers.  Embarcadero's Delphi Certification Program offers two levels: Delphi Certified Developer and Delphi Certified Master Developer. “

I just passed the Delphi Developer Certification exam and thus I became a Certified Delphi Developer.
Certified Delphi Developer
 Now, I want you to become certified as well :-) So, mind this: 
  • This exam is conducted over the Internet without supervision. That means you can take the exam at home (or wherever you prefer) at your own pace. You don’t need to go to a particular place to take the exam: you just need an Internet connection and that’s pretty much it.
  •  The exam is cheap. It only costs $49USD.Consider for example that the prices for .NET or Java certifications are much higher.    
  • You can pay for the exam code online (you need an exam code to take the certification exam). Theoretically, you can pay it using VISA, MasterCard and Paypal. Warning: I tried with my VISA and Master Card cards and it didn’t work. It seems that there is (was) something wrong with the payment system. At the end, I managed to perform the payment through Paypal.
  • The exam contains 60 questions to be answered in 60 minutes. The time is plenty; so, don’t worry about it.
  • Be careful with the syntax questions: even if you are an experienced Delphi programmer, I would advise you to review the syntactical elements of the language before taking the test. Most times our memory becomes dusty after too much time relaying on the code completion features of the IDE.
  • Take a look at the Delphi Developer Certification Study Guide. Make sure you cover all the topics targeted for the exam. Remember: all topics go under examination.
I wanted to take the Delphi Master Developer Certification exam as well, but guess what? - This exam is supervised and I would need to travel to USA to take it. I think I will wait until it becomes available (hopefully) in Canada.

I belief the introduction of these certification programs is proof that Embarcadero is willing to gain a good portion of the programming market. By taking the exams you become part of the effort of bringing Delphi to the arena once more…I believe it’s worthy.

I recently found this Delphi Certification Webinar video by Andreano Lanusse.