A very simple facade

< back to overview

In one of our latest project we wanted to use some sort of an event system that would make it possible for components to dispatch events to each other even though they are not aware of each other or are not in the same displaylist structure. In that last example we would just use the default event class that comes with AS3.

Now, when working with pureMVC I noticed this really great thing called the Façade. The façade enables you to do just that. You dispatch a notification via the façade and all connected components would be notified of this certain notification.

Because we didn’t want to use the whole PureMVC framework, I developed a small set of classes that would implement only the notification system. It’s very basic and only allows you to send messages. We skipped the data part because we are working with a centralized Model class. I will update this in another blog post so that you can send data back and forth.
The classes are compatible with both flash and flex. If there is any interest, it can be ported to AS2.

It basically consists of three classes: the Façade class, the INotifier interface and an optional class Notifications.
What you will do first is let your class (either visual or abstract) implement the interface INotifier. This will force you to implement two functions that the Façade needs to connect this class to a notification.

	public interface INotifier
	{
		/**
		 * This function is called when you register a component with the Facade.
		 * It is necessary to attach your component to certain notifications
		 *
		 * @return		array		return list of notifications you are interested
		 * 					in as strings. You can store these notification
		 * 					types in the Notification class as static members
		 */
		function listNotifications():Array 
 
		/**
		 * This function is called by the Facade when a notification is dispatched.
		 *
		 * @param		notification		The notification type. best practise is to store
		 * 						the notification types in an external class as
		 * 						static members.
		 */
		function handleNotification(notification:String):void
	}

So let’s take a look at a small example.

This movie requires Flash Player 9

The square and the circle are both waiting for an APP_START notification. When the app is started, the circle and square will be notified and call their draw() function to draw something to the screen.
When both elements are drawn, they are clickable. The circle will listen for a click event on the square component and vice versa. Also the application is listening for both events to display which child is pressed in a textfield on the stage.
So if we take a look at the displaylist, it looks as follows:

>  Stage
>  Facade_example
>  Square
>  Circle
>  txtAction

So let’s run over the code step by step.
First let’s take a look at the Square class. I’m not covering the draw class since this is not that important.

public class Square extends Sprite implements INotifier
{
		public function Square()
		{
			super();
			init();
		}
		private function init():void
		{
			Facade.instance.registerView(this);
			addEventListener(MouseEvent.CLICK, clickSquare);
		}
....

First thing you want to do is implement the INotifier interface. This will force you to implement the two basic functions needed to register a view to the facade.
In the init function I call the registerView method of the Facade (which is a singleton class). As a parameter I send a reference to the class by using the this keyword. This works both for displayObjects as abstract classes!
Classes can also be registered outside the class, I will show this in a minute with the myCircle class.
When you call the registerView method, the Façade is going to look for a (public) function called listNotifications. (Which you had to write when implementing the INotifier interface)
In this function you return an array with the notification types you want to be notified of

	/**
	* This function returns list of notifications you are interested in
	*/
	public function listNotifications():Array {
		return [Notification.CLICK_CIRCLE, Notification.APP_START];
	}

In the above example, I stored the notification types as static members of the class Notification. This is just a class I use to store all notification types to prevent typing errors or to refactor notifications really easily.
The façade will look over the notifications and that’s it, your class Is now connected!
The registerview method can be called before the class is added to the displaylist and also inside the constructor of the class.
Now what if you don’t want to call the registerView method from within the class? Well it’s perfectly possible to call it from an external source. Just take a look at this part of the façade_example.as class:

	ci = new Circle();
	ci.x = 260;
	ci.y = 100;
	addChild(ci);
 
	Facade.instance.registerView(ci);

Here I first create a new instance of the myCircle class, and register the view from the main class. This is possible because all you have to pass is a reference to an object that implements the INotifier class. Be aware that all the implemented methods must be public.
Ok, so that’s all for the first part, connecting to the façade, now the next step is to actually send and receive notifications.

First, let’s send a notificiation:

	Facade.instance.dispatchNotification(Notification.APP_START);

Again, I’m using a static variable for the notification type. But basically it is string based so you can also use strings.
The façade will now look for all the classes that are connected to this type of event and call a function on all the connected views, which is the handleNotification function (should also be public).

public function handleNotification(notification:String):void {
	switch(notification) {
		case Notification.CLICK_CIRCLE:
			draw(Math.random()*0xffffff);
		break;
		case Notification.APP_START:
			draw();
		break;
	}
}

So this is the handleNotification implementation for the square. Basically you evaluate the value of the notification using a switch statement and execute the right method accordingly.
Ok, so that’s pretty much all you have to know to start using these classes. Let’s recap:

1.  Implement INotifier
a.  Write listNotifications function
b.  Write handleNotification function
2.  Register view to Façade. From inside the class or outside
3.  Dispatch notifications through the dispatch Notification method of the façade.

And then last but not least, you can also unregister a view from its notifications. This will clear all the references to the object (in the Façade) and makes sure the class is no longer notified when a notification is dispatched.

	Facade.instance.unregisterView(this);

There will probably be a lot implementations about this principle available out there, but nevertheless I wanted to give it a shot anyway :-) I hope you can use it.

Source files: here (Flex builder project)

Future development plans in order of importance:

- Dispatch notifications with data attached (The code for this is actually very easy).
- Create a debug module to see which notifications are dispatched.
- Map notification types directly with functions.
- Dispatch notifications among different swf instances.

  • Share/Bookmark
< back to overview

Comments

No comments yet

Make a comment