ActionScript Facade Design Pattern: The Cat Herder

The bigger and more complex a system based on subsystems gets, the more difficult it is for a client to make requests and get what is expected. The Facade acts as an interface to simplify communication with the elements that make up the subsystem and the client. So instead of communicating with all of the components of the subsystem, the client interacts with a single component, the Facade.

The class diagram for the Façade looks a good deal different from most other design patterns. The classes that make up the subsystem are intentionally vague to represent any subsystem. The problem, though, is clearly illustrated by the network of possible connections between the classes in the subsystem and how a client might run into problems when it needs to interact with them all. Figure 1 shows a modified Façade class diagram. In the original GoF diagram, the client is not listed as a participant—only the Façade and the subsystem classes. However, following the Freemans’ diagram (with some slight adjustments of my own to make it closer to the GoF diagram) I included a client but made it implicit.

Figure 1: Facade Class Diagram

Gamma and associates use the compiler as an example of a Façade. It communicates with the different computer system classes, and anything outside of the subsystem communicates through the compiler. The Freemans (Head First Design Patterns) use an example of a super remote control that controls several different components of a home theater. Included are eight components to control such features as a screen, amplifier, tuner and even a popcorn maker. In each case, the point is that a single interface is easier to deal with than several. At the same time, the subsystem can remain loosely coupled and all the client has to worry about is communicating with the Façade.

A Simplified Interface for Using Chroma Keys

The subsystem can be anything from a collection of interacting classes, to other design patterns or even a collection of design patterns. Following the examples of GoF and the Freemans, I decided to see if I could make a Façade design pattern to clarify the use of chromakeys with streaming videos. The process requires a good deal of steps and different software, each of which can be treated as a class.

  1. Set up a chroma screen. (BackDrop)
  2. Add the proper lighting (Lighting)
  3. Film the shots (Film)
  4. Transfer video to digital file using Quicktime (Conversion)
  5. Edit the video using Adobe Premier and save as avi file (Edit)
  6. Open avi file in Ultra 2 for adding chroma key effects and backdrops (Chroma)
  7. Add avi file to Flash video encoder for conversion into flv file. (MakeFLV)
  8. Create an FMS/Flash/Flex app to play flv file and publish it (Stream)

Any one of the above steps can be simple or complex, but trying to encapsulate it as a process can be daunting. To get started in seeing how the Façade design pattern works, I made a simple subsystem of two classes (BackDrop and Film) that are part of the process of creating a streaming video with chroma key effects. Normally, you’d not need a Façade for such a simple subsystem, but two classes work as well as ten to show how to create and use the Façade design pattern.

The Minimalist Façade

First, we’ll create the subsystem of the steps to set up a chroma screen and film the video. (Both have been simplified.) The BackDrop class has methods for setting up and putting away the chroma screen as well as choosing a blue or green screen. The Film class simply starts and stops filming.

BackDrop.as

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
package
{
	public class BackDrop
	{
		private var task:String;
 
		public function BackDrop(task:String)
		{
			this.task = task;
		}
 
		public function setBlue():void
		{
			trace(task+"Set blue screen");
		}
 
		public function setGreen():void
		{
			trace(task+"Set green screen");
		}
 
		public function setStands():void
		{
			trace(task+"Set up supports for screen");
		}
 
		public function storeStands():void
		{
			trace(task+"Take supports down and store");
		}
 
		public function storeBackdrop():void
		{
			trace(task+"Fold backdrop and put away");
		}
	}
}

Film.as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package
{
	public class Film
	{
		private var task:String;
 
		public function Film(task:String)
		{
			this.task = task;
		}
 
		public function shoot():void
		{
			trace(task+"Start filming");
		}
 
		public function stopShoot():void
		{
			trace(task+"Stop filming");
		}
	}
}

As you can see, the above classes are simple ones with nothing more than a constructor class and collection of methods. Both constructor classes are parameterized, suggesting openness for communication and variety.

Next comes the Façade. This façade class is named FilmFacade and holds references to both the BackDrop and Film classes. It contains two methods: one to start the chroma key process and one to end it. Within each method are the different operations based on methods from the classes in the subsystem.

FilmFacade.as

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
package
{
	import flash.display.Sprite;
 
	public class FilmFacade extends Sprite
	{
		private var film:Film;
		private var backDrop:BackDrop;
 
		public function FilmFacade(film:Film,backDrop:BackDrop)
		{
			this.film = film;
			this.backDrop = backDrop;
		}
 
		public function doChroma():void
		{
			trace("Start project");
			backDrop.setStands();
			backDrop.setGreen();
			film.shoot();
		}
 
		public function endChroma():void
		{
			trace("Finish project");
			film.stopShoot();
			backDrop.storeBackdrop();
			backDrop.storeStands();
		}
	}
}

The payoff for the client class (cleverly named Client) is that it does not have to deal directly with the classes in the subsystem. Instead, the client only deals with the FilmFacade class.

Client.as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
package
{
	import flash.display.Sprite;
 
	public class Client extends Sprite
	{
		private var film:Film;
		private var backDrop:BackDrop;
		private var filmFacade:FilmFacade;
 
		public function Client()
		{
			film = new Film("The Chroma Process at Work: ");
			backDrop = new BackDrop("Acme Back Drops: ");
			filmFacade = new FilmFacade(film,backDrop);
			filmFacade.doChroma();
			filmFacade.endChroma();
		}
	}
}

When you test this application, you will see the following output:

Start project
Acme Back Drops: Set up supports for screen
Acme Back Drops: Set green screen
The Chroma Process at Work: Start filming
Finish project
The Chroma Process at Work: Stop filming
Acme Back Drops: Fold backdrop and put away
Acme Back Drops: Take supports down and store

The client simply instructs the Façade class to start and stop the chroma key operation. With only two classes in the subsystem, that’s no great shakes, but were the client to deal directly with the subsystem classes (which it can do), it would be a bit more involved, even with only two classes in the subsystem. As the subsystem becomes more complex, the need for the Façade grows.

The Moral to the Façade Design Pattern: Don’t Talk to Strangers

One of my favorite features of Head First Design Patterns is its clear rendering of design principles. Most of these principles are directly or indirectly from GoF, but sometimes the Freemans put together a principle that appears to be constructed from the logic of the pattern. For the Façade (and Adapter) pattern, they put forth the Principle of Least Knowledge. This principle pre-dates design patterns by a few years (1987) but is still an object oriented programming principle. Characterized as

Only talk to your immediate friends

the principle works something like this: A can talk to B, and B can talk to A and C, but A cannot talk to C without going through B. The Façade, is the interface between the client and the subsystem and in order to communicate with the subsystem, the client must go through the Façade. That follows the Principle of Least Knowledge.

5 Responses to “ActionScript Facade Design Pattern: The Cat Herder”


  1. 1 Russell

    a very nice example, cheers for taking the time to break this down

  2. 2 Bill

    Russell,

    It’s always our pleasure. I’m still hammering away on the Prototype and hope to get it done in the not too distant future.

    Bill

  3. 3 Anggie Bratadinata

    Great post, Bill. Keep them coming!

    I really enjoyed your book and blog. I’m no pattern freak but your book & the Freemans’ are permanent residents of my desk.

    When you have time, could you write some stuff on Fowler’s GUI patterns? (http://martinfowler.com/eaaDev/uiArchs.html)

    Thanks!

  4. 4 Bill

    Hi Anggie,

    Fowler’s GUI patterns look interesting indeed. However, given that they’re MVC-related, Chandima may do a better job on that. I’ve got the seemingly impossible task of trying to get the Prototype design pattern nailed down for ActionScript. Right now I’m working through the elements of recursion in the dp, and if you have any ideas about getting the Prototype right, I’d like to hear those as well!

    Take care and thanks for the GUI patterns,
    Bill

  1. 1 localToGlobal » Blog Archive » news review -> 39th week of 2008

Leave a Reply