Home > Bridge, Saturated Bridge > ActionScript 3.0 Saturated Bridge Design Pattern 1: Intention

ActionScript 3.0 Saturated Bridge Design Pattern 1: Intention

Independent Variationby Decoupling Abstractions and Implementations

Independent Variation by Decoupling Abstractions and Implementations

Independent Implementation?

The concept that you can decouple an abstraction from its implementation sounds flat out bizarre. Whether talking about an interface or an abstract class, how in the world is it possible to implement a concrete class that is not affected by changes in the interface? If the abstraction varies, the concrete implementation is either going to change or crash. If you use an interface, you’ll have some kind of abstract method set up that is implemented by a class using the interface and its signature. If I change the interface even minutely, something is going to change in the implementation or it will crash. Suppose I change the return type in one of the methods from a Number to a String, what’s going to happen when I run the program? It will throw an error.

For example, try the following:

?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
//Client
package
{
	import flash.display.Sprite;
 
	public class Client extends Sprite
	{
		private var doFirst:IFace;
		public function Client()
		{
			doFirst=new Imp1();
			trace(doFirst.doThing());
		}
	}
}
 
//Interface
package
{
	public interface IFace
	{
		function doThing():Number;
	}
}
 
//First (correct) Implementation
package
{
	public class Imp1 implements IFace
	{
		public function doThing():Number
		{
			return 55;
		}
	}
}

That works just as expected. No big deal, the interface implementation is correctly formed. Now, make the following variation and try it:

?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
//Modified Client to call new implementation
package
{
	import flash.display.Sprite;
 
	public class Client extends Sprite
	{
		private var doFirst:IFace;
		public function Client()
		{
			doFirst=new Imp2();
			trace(doFirst.doThing());
		}
	}
}
 
//Modified implementation
package
{
	public class Imp2 implements IFace
	{
		public function doThing():String
		{
			return "Hello World!";
		}
	}
}

The only thing that was changed was the return data type from Number to String. Here’s the Crash results:

Line 3 1144: Interface method doThing in namespace IFace is implemented with an incompatible signature in class Imp2.

So how can you have independent variation between an abstraction and its implementation?

The Bridge to the Moon

When thinking about an image for this series on the Bridge design pattern, I considered a number of bridge images. However, the Bridge intention is to,

Decouple an abstraction from its implementation so that the two can vary independently.

The idea of a bridge to the moon popped up because the earth and the moon have different orbits (and a few other things) but share much in common and exert an influence on one another. The idea of a bridge to the moon is one way to think about decoupling and connections at the same time. An even better way is to take a look at the Bridge class diagram in Figure 1:

<em><strong>Figure 1:</strong> Bridge Class Diagram</em>

Figure 1: Bridge Class Diagram

Now, when we think about decoupling an abstraction from its implementation we can see that the Gang of Four made both the abstraction and implementation abstract! The implementation in the sense that we use extend from an abstract class or implements from an interface has a whole new meaning.

When an aggregate relationship exists between two classes (or interfaces) they create something akin to a concurrent object with different implementations possible. In this case the aggregate relationship is between two interfaces (or abstract classes), and you can begin to understand independent variation. So we need to look more closely at what exactly varies.

Orthogonal Design

In the roughest sense, orthogonal refers to two (or more) elements that can vary independently of one another. For example, in our original post on the Bridge pattern, color and size were two features that varied in the example. In that sense color and size are orthogonal. Either could change and have no effect on the other. In the original example, a simple backdrop for a video could vary in size and color. However, the orthogonal character of the design may have been masked in a utility (helper) class that I added.

In searching for a better characterization of orthogonal design, I came across an article, Design Pattern Orthogonal Component, that provides an example used with a state machine. In the state machine, the alarm clock is divided into two orthogonal regions: timekeeping and alarm. According to the article, dividing the state machine into two orthogonal regions is considered fairly expensive because each region requires a separate state-variable and extra work in dispatching events (e.g., ringing an alarm.)

As an alternative to orthogonal regions, the article suggests orthogonal components. In order to connect up the alarm with the alarm clock the article shows how to use aggregation to accomplish that linkage. It points out,

Concurrency virtually always arises within objects by aggregation; that is, multiple states of the components can contribute to a single state of the composite object.

Figure 2 shows how the alarm clock and alarm are linked through aggregation. (Figure 2 diverges from the original to provide a clearer picture of an orthogonal component.)

<em><strong>Figure 2: </strong>Orthogonal Component</em>

Figure 2: Orthogonal Component

Also unlike the original, Figure 2 shows the two parts of the orthogonal component as abstract, implying either abstract classes or interfaces.

If we think about this a bit, it reflects how things work in the real world. Following the example of an orthogonal component being an alarm clock, we can imagine many different implementations of both the clock and the alarm. I may have an old-fashioned wind-up alarm that goes “ding, ding, ding” or a clock radio that plays Wagner’s Walkürenritt to wake me up. Figure 3 shows a more graphic illustration of the implementations of the concepts in Figure 2—remember the AlarmClock and Alarm are abstract in that figure:

<em><strong>Figure 3: </strong>Alarm Clocks and Alarms</em>

Figure 3: Alarm Clocks and Alarms

Figure 2 is not a bridge but an orthogonal component—at least a variation of an orthogonal component because I added the abstract container and components. It is meant to provide a sense of how one can create linked but mutual variation in a design. Figure 3 represents an implementation of Figure 2, and not a Bridge design pattern. This is just the first step in fully understanding the Bridge design pattern.

Share

Related posts:

  1. New Twist on the ActionScript 3.0 Bridge Pattern
  2. An ActionScript Bridge Design Pattern: Flexibility Making Backdrops

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>