Archive

Archive for the ‘Template Method Pattern’ Category

Beginner's First Design Pattern: The Template Method

I'm a Design Pattern Virgin too!

It's my first time too!

The Template Method: A Design Pattern with a Principle

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:

<em><strong>Figure 1: </strong>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:
playkilroy

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

?View Code ACTIONSCRIPT
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:

?View Code ACTIONSCRIPT
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:

  1. An abstract class
  2. A method that orders the steps in an algorithm
  3. 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.)

?View Code ACTIONSCRIPT
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.

?View Code ACTIONSCRIPT
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.

?View Code ACTIONSCRIPT
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.

Share

Hollywood Principle: Don’t Call Us; We’ll Call You—ActionScript 3.0 Template Design Pattern goes Hollywood!

bucketrulehollyThe problem in understanding the Hollywood Principle is that it is too often glossed over as a type of inversion of control. In most respects, the Hollywood principle is really about the direction of calls. Where it gets a little confusing is when you assume the natural order of programming is from bottom to the top, with the bottom making calls to the higher levels. At one time, much programming was “bottom-up” in this sense, but that’s been quite a while. Therefore, when talking about inversion, you may be wondering, inversion from what? In fact, the late John Vlissides (one of the Gang of Four) starts off a discussion of the Hollywood Principle, noting,

The Template Method pattern leads to an inversion of control known as the “Hollywood Principle,….” (1996)

As we know, Dependency Inversion is better understood as Abstraction Dependency—both higher and lower level components come to depend on abstractions. If we think depend on abstractions we have no need to even consider inversion. Doing so only confuses the issue. So, if we examine the Hollywood Principle, let’s do so in terms of what it does in its own right—what is its focus?

The Hollywood Principle holds that higher level components should call lower level components, but lower level components should not call higher level components.

So, if we take that focus of the Hollywood Principle we can better discuss its unique features. Is it related to the other principles of OOP? Of course it is, but let’s just focus on the point it makes.
Read more…

Share

Flexibility Pays Off with Template Method

August 23, 2007 1 comment

This is a testimonial of sorts for the capacity to easily change an application created with design patterns. Recently Adobe put up a version of a player that streams H.264 formats–these are files like Apple’s .mov and MP4, among others. After fumbling around for a while creating the files–one video .mov using iMovie and a M4a audio using Garage Band, I went to test them on a progressive download app I had handy that was set up to play audio using the Sound class and video with NetConnection(null) and NetStream. The only problem was that the streaming audio (m4a) file required a NetStream instance and would not work with the Sound class.

Because the classes for handling audio were set up around the Sound class, I thought this would be a major chore, but all I had to do was to make changes in one class. After the changes were made, it worked fine. The best part is that the structure of the Template Method did not interfere with any of the other elements in the application. So while the application may be fairly complex for the simple task of playing video and sound, when things change, as they always do, making the changes in the application were simple.

The application can be found at: http://www.sandlight.com/player9/. Keep in mind that no FLV files are used but that a genuine MOV file being played in Flash using progressive download and the sound is from a M4a file, the same file format as the ones used for iTunes–all sitting fat and happy and working. You’ll need to go to Adobe Labs and download the Flash 9 player (Beta) to see this at work.

Share