Special

Introducing the “Welcome to Xojo” Bundle!

New to Xojo and looking for guidance? We've put together a terrific bundle to welcome you! Xojo Bundle

This bundle includes six back issues of the magazine -- all of year 21 in printed book and digital formats -- plus a one-year subscription (beginning with 22.1) so you'll be learning all about Xojo for the next year. It's the perfect way to get started programming with Xojo. And you save as much as $35 over the non-bundle price!

This offer is only available for a limited time as supplies are limited, so hurry today and order this special bundle before the offer goes away!

Article Preview


Buy Now

Issue 7.1

FEATURE

The Template-Method-Pattern

Motivation: Having some Algorithms, that differ in details, but not in Principle

Issue: 7.1 (November/December 2008)
Author: Jens Bendig
Author Bio: When he was young Jens Bendig was fascinated by three things: motorbikes, computers, and movies. Now he rides a motorbike, produces animated movies, and develops software. He seems to be a straightforward character.
Article Description: No description available.
Article Length (in bytes): 17,836
Starting Page Number: 22
Article Number: 7111
Resource File(s):

Download Icon project7111.zip Updated: 2008-11-01 11:51:00

Related Link(s): None

Excerpt of article text...

I have read so many articles about haute-cuisine and molecular-cooking that today I want to write about good and honest baked potatoes. By that I mean, we often have programming problems that make our heads smoke, but sometimes those problems can be solved by an old, well-known, and simple design. Here comes such a problem and a clear, easy, and straightforward way of solving it. You'd do so in REALbasic like in any other object-oriented language.

A Common Problem

Do you sometimes have a problem like this: I have 2 (or 20) Classes, they are similar in their basic algorithm (i.e., they have about the same sequence of doing things, but in detail, they are doing different things). You see that you have double code, but it's not so clear why. You'd like to get an abstraction to avoid the double code, but you are not sure about how to do so. If you derive from a Base-Class (Super-Class), doesn't that mean to carry the Algorithm to the derivatives? Or can we centralize the Algorithm in the base-class and keep the Variations for the Derivatives?

Yes, we can: with a design pattern called "Template-Method." It's helpful, if you have a fixed sequence of "something" but a lot of variations in that "something." Is it complicated to make or difficult to understand? Does it need sophisticated mechanics? No, it's just the good and straightforward use of the good old mechanism called inheritance.

...End of Excerpt. Please purchase the magazine to read the full article.


Errata (2008-11-09)

The following Code Listings were inadvertently omitted from the article.

Listing1: Code for coffeeMaker and teaMaker

// coffee-button
Sub Action()
  dim maker as coffeeMaker
  maker=new coffeeMaker(output) // output is the instance-name of a listbox
  maker.produce()                   // producing means to fill the output for the user
End Sub
// tea-button
Sub Action()
  dim maker as coffeeMaker
  maker=new coffeeMaker(output)
  maker.produce()
End Sub

//Code of the coffeeMaker-Class
Sub Constructor(output as listbox)
  me.plog=output // keeping the output-listbox as property, my methods will log there
End Sub

// The algorithm of the coffee-maker: 4 Steps of production
Sub produce()
  me.heatWater() // step1
  me.filtering() // step2
  me.fillCup() // step3
  me.addSugarAndMilk() // step4

  me.plog.AddRow("finished")
  me.plog.AddRow("")
End Sub

// Details of the algorithm, description of the 4 steps itself:
Private Sub heatWater()
  me.plog.AddRow("Heating water...")
End Sub
Private Sub filtering()
  me.plog.AddRow("Let the Water run through a Filter with Coffee")
End Sub
Private Sub fillCup()
  me.plog.AddRow("Fill the cup with coffee")
End Sub
Private Sub addSugarAndMilk()
  me.plog.addrow "Adding sugar and milk"
End Sub

// Code of the teaMaker-Class
Sub Constructor(output as listbox)
  me.plog=output // hmm. looks exactly the same as the constructor of the coffeeMaker-class
End Sub

Sub produce()
  me.heatWater() // identical to coffeeMaker step1 
  me.letBrew() // different to coffeeMaker step2 
  me.fillCup() // identical to coffeeMaker step 3
  me.addCitrone() // different to coffeeMaker step 4

  me.plog.AddRow("finished")
  me.plog.AddRow("")
End Sub

Private Sub heatWater()
  me.plog.AddRow("Heating water...")   
End Sub

Private Sub letBrew()
  me.plog.AddRow("Fill the hot Water into Can with Tee-Egg")
End Sub

Private Sub fillCup()
  me.plog.AddRow("Fill the cup with Tee")
End Sub

Private Sub addCitrone()
  me.plog.addrow "Adding Citrone"
End Sub

Listing 2: Abstract Base-Class hotBeverageMaker

Sub Constructor(logOutput as listbox, name as string)
  me.plog=logOutput
  me.plog.AddRow("new hot beverage: "+name) // the Parameter name will be given by the concrete hot Beverage, derived from this class
End Sub

// the following method is the template method: The Controller of all the derived Details
Sub produce()
  me.heatWater()   //common for all hot beverages
  me.pour() // depending on kind of beverage  
  me.fillCup()       // common for all hot beverages 
  me.addIngredients() //depending on kind of beverage
  
  me.plog.AddRow("finished") // served with a smile could be put here for every Beverage!
  me.plog.AddRow(" ")
End Sub

Protected Sub heatWater()
  plog.AddRow("heating water") // this code will do the work for all derived classes
End Sub

Protected Sub pour()
  me.plog.AddRow("ERROR: base-class does not know how to pour")  
End Sub

Protected Sub fillCup()
  me.plog.AddRow("filling the cup with"+me.pname)  // this code will do the work for all derived classes
End Sub

Protected Sub addIngredients()
  me.plog.AddRow("ERROR: Don't know how to add Ingredients")
End Sub

Listing3: coffeeMaker, teaMaker

// code for the coffeMaker
Sub Constructor(logOuput as listbox)
  // Calling the overridden superclass constructor.
  Super.Constructor(logOuput,"Coffee")
End Sub

Protected Sub pour()
  me.plog.AddRow("putting Coffee into Filter and fill with hot Water")
End Sub

Protected Sub addIngredients()
  me.plog.AddRow("Adding some Milk and sugar for the customer")
End Sub

// code for the teaMaker
Sub Constructor(logOuput as listbox)
  // Calling the overridden superclass constructor.
  Super.Constructor(logOuput,"Tea")
End Sub

Protected Sub pour()
  me.plog.AddRow("putting Tee into Can and fill with hot Water")
End Sub

Protected Sub addIngredients()
  me.plog.AddRow("Adding some Citrone")
End Sub