Beginner's First Design Pattern: The Template Method

It's my first time too!
In learning OOP and Design Patterns, what you’re learning is a set of principles with associated programming patterns. The Template Method is a valuable starting place because it is used to illustrate the OOP/DP principle called The Hollywood Principle. Be sure to go over the more detailed post on the Hollywood Principle, but for here, you just need to become familiar with the idea that higher level components (like parent classes and interfaces) should call lower level components (like concrete classes), but lower level components, should not call higher level components. The principle is called Hollywood, because the casting director tells the budding actor,
Don’t call us, we’ll call you.
The parent class tells the child class the same thing.
Class Diagram
In order to understand a class diagram, you need to understand class relations. If you understand how to work with an UML, you’re ahead of the game; however, if not, we’re prepared a 4-part series to help you understand the UML and the whole concept of relations between pattern participants. Figure 1 shows the class diagram for the Template Method:

Figure 1: Template Method Class Diagram
After you’ve studied the class diagram for a bit, you can see that it’s made up of one abstract class (all italicized bold lettering indicates an abstract class or interface), and one subclass. One of the operations in the abstract class is concrete (Template Method) and the others are abstract (primitive operations). The abstract methods are italicized.
The template method is made up of the steps in an algorithm, some of which are abstract and some that can be concrete. The template method orders the steps in the algorithm, but the concrete subclass provides concrete implementations of the abstract methods using override. The following two buttons provide a preview of Play and all of the files are available for download:
![]()

Abstract Classes and Primitives
One of the more poorly defined concepts in computer programming is that of primitives. Usually when we think of primitives, we think of basic data types like numbers, strings and Booleans. However, the Gang of Four parenthetically note that primitive operations are nothing more than abstract methods. For example, the following is an abstract operation (or method):
1 2 3 4 5 | protected function DoUI():Sprite { throw new IllegalOperationError("Must override"); return null; } |
Because ActionScript 3.0 has no abstract classes or methods, you have insure that the abstract methods will not be directly instantiated, and one way to do that is to add the illegal operation line. Further to have the proper signature, the method must include some kind of return statement, and a null value does the trick. In the concrete implementation, each primitive operation is overridden and provided concrete operations.
Within the abstract class, you can have both concrete and abstract methods. One of the advantages of an abstract class (compared with an interface) is that abstract classes can have some concrete methods. For example the following template method uses two primitive operations and a concrete one. It’s just is to order the steps of the algorithm, which in this case has three:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ...abstract class.. public function templateMethod() { DoLogo(); DoUI(); DoInfo(); } protected function DoUI():Sprite { throw new IllegalOperationError("Must override"); return null; } protected function DoInfo():TextField { throw new IllegalOperationError("Must override"); return null; } protected function DoLogo():Sprite { var logo:Sprite=new Sprite(); return logo; } ...abstract class |
So let’s stop a second and consider why and how we’d use a Template Method design based on the following:
- An abstract class
- A method that orders the steps in an algorithm
- At least one abstract method that is overridden by a concrete class that implements the abstract class.
The abstract class affords the programmer flexibility when similar algorithms are used again and again but with slightly different implementations. For example, you may find yourself using a “page algorithm.” The page algorithm loads your logo, creates a UI and then creates content. The logo loading part is going to be the same as you use your logo over and over again. However, the UI and content can vary in several different ways. For that, you need flexibility.
Page Arranger
To get started on the algorithm for a page arranger, we’ll start with the abstract class which is named IServices. One convention you will find in OOP is using an “I” prefacing all Interfaces. I like to do the same thing with abstract classes because other than the concrete properties and methods, you should think of them as a type of interface. (If you’re just getting started in OOP and Design Patterns, you might want to check out Beginners Start to see where the files go in Flash and Flash Builder.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | package { import flash.display.Sprite; import flash.errors.IllegalOperationError; import flash.net.URLRequest; import flash.display.Loader; //Abstract class. Do not instantiate directly //Extend the class for concrete child classes public class IServices extends Sprite; { private var logoPix:URLRequest=new URLRequest("logo.swf"); protected var uiPix:URLRequest; protected var infoPix:URLRequest; private var logoLoader:Loader=new Loader(); protected var uiLoader:Loader=new Loader(); protected var infoLoader:Loader=new Loader(); private var page:Sprite=new Sprite(); private var logoSprite:Sprite=new Sprite(); protected var uiSprite:Sprite=new Sprite(); protected var infoSprite:Sprite=new Sprite(); public function templateMethod():Sprite { page.addChild(DoLogo()); page.addChild(DoUI()); page.addChild(DoInfo()); return page; } protected function DoUI():Sprite { throw new IllegalOperationError("Must override"); return null; } protected function DoInfo():Sprite { throw new IllegalOperationError("Must override"); return null; } protected function DoLogo():Sprite { logoLoader=new Loader(); logoLoader.x=0; logoLoader.y=0; logoLoader.load(logoPix); logoSprite.addChild(logoLoader); return logoSprite; } } } |
In the abstract class IServices, you can see two abstract methods (primitive operations), and two other methods—DoLogo and templateMethod. The DoLogo is going to be the same assuming that the company keeps the same logo; so you might as well set it up and let the child classes reuse it when they extend the abstract class. However, the UI and information may change, and so both of the methods for what they may include are left up to the concrete implementation.
Next, enter the concrete implementation of the abstract class. In the following you will see that both of the abstract methods are not implemented.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | package { import flash.display.Sprite; import flash.net.URLRequest; import flash.display.Loader; public class ConcreteService extends IServices { override protected function DoUI():Sprite { uiPix=new URLRequest("UI.swf"); uiLoader=new Loader(); uiLoader.x=0; uiLoader.y=110; uiLoader.load(uiPix); uiSprite.addChild(uiLoader); return uiSprite; } override protected function DoInfo():Sprite { infoPix=new URLRequest("info.swf"); infoLoader=new Loader(); infoLoader.x=150; infoLoader.y=110; infoLoader.load(infoPix); infoSprite.addChild(infoLoader); return infoSprite; } } } |
Keeping in mind that you never implement an abstract class, but you want to program to the abstract class (think interface), you will need a client class to request the use of the concrete implementation. However, by declaring the requesting instantiation through the abstract class, you can keep the binding loose. So the variable tm is typed to IServices but instantiates ConcreteService.
1 2 3 4 5 6 7 8 9 10 11 12 | package { import flash.display.Sprite; public class Client extends Sprite { private var tm:IServices=new ConcreteService(); public function Client() { addChild(tm.templateMethod()); } } } |
As you can see, there’s not much work for the Client. All it has to do is to use addChild to place the returned Sprite object to the display area. The templateMethod() operation is wholly inherited from the IServices class, but at the same time the ConcreteService class allows flexibility of what goes into the DoInfo and DoUI methods.
Play around with this example. The best way is to create some .swf files that you can use instead of the ones provided for download on this post. You’ll begin to see how flexible this design pattern is and how easy it is to use.




Tight Code and Tighter Programmers

Bill Sanders
Recent Comments