Saturated Strategy 2: First Implementation

You need to add your own algorithm to understand the pattern's value
In this second installment of looking at the Strategy pattern, we’ll take a simple application to use as a point of reference. Last time we looked at the participants, and this time we’ll begin with a simple class diagram and then implement the pattern. As you recall from the first post in the Saturated Strategy pattern series, the pattern has three participants: Strategy (an interface), Context, and ConcreteStrategy. Further, while no Client class is a participant in the pattern or even implied (shown by a ghosted class box), it is important. It provides the request for a ConcreteStrategy. However, it does not do so through the Strategy participant, but instead it goes through the Context.
The Class Diagram
At this point it makes more sense to look at a class diagram of the Strategy because you know what each participant does from the first installment of this series. Figure 1 shows the participants in a class diagram:

Figure 1:Strategy class diagram
As you can see no Client class is included—not even the implied. So how does one go about making requests? In the first installment, you saw that the Client uses the Context class to make requests for a ConcreteStrategy. Further, the aggregation symbol (arrow with the diamond on the tail) shows a fairly strong connection between the Context and Strategy. So how do we go about implementing a basic design using the participants given in the class diagram? (Turn the page to see the first implementation used in this series.)
Strategy Interface
The family of algorithms we’ll be considering is one made up of navigation devices. So, all we need is some method that has a framework for guiding an object to a location. (Click the download button to download all of the files:)
1 2 3 4 5 6 7 | package { interface IStrategy { function findLocation(); } } |
That provides a pretty wide range of possible implementations, but the idea is to set up a flexible, loosely coupled application. Further, as is the case in all interfaces, there’s no specific content—only the framework.
ConcreteStrategies
To begin, the first concrete strategies will be simple. Each one indicates a different kind of navigation strategy, but all we really need to see the structure of the design pattern is some kind of unique trace() statement indicating different navigation strategies. This example uses GPS, Compass and a Map: (Note: Save each as a separate .as file using the class name as the file name plus the .as extension.)
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 { class StratGPS implements IStrategy { public function findLocation() { trace("Follow the map on the screen"); } } } package { class StratCompass implements IStrategy { public function findLocation() { trace("Proceed heading 290."); } } } package { class StratMap implements IStrategy { public function findLocation() { trace("Stop, look at the map. Find the turn-off number, drive to the turn-off and stop again for the next segment."); } } } |
All that’s required for an implementation is to include all of the methods in the interface. The IStrategy interface has only a single method; so that single method is included in all of the implementations.
Context
As you recall from Part I of this series, the context is quite busy. It is configured with a concreted strategy and it maintains a reference to a strategy object. What does that look like using ActionScript 3.0? The following shows one such implementation of the Context participant:
1 2 3 4 5 6 7 8 9 10 11 12 13 | package { class Context { private var strategy:IStrategy; public function Context(strategy:IStrategy) { this.strategy=strategy; this.strategy.findLocation(); } } } |
The concrete strategy is typed as IStrategy so that any concrete strategy object can be passed as a parameter in the constructor function. This is where you can see 1) programming to an interface instead of an implementation, and 2) loose coupling because it commits only to the interface and no single concrete implementation.
The Client
While there’s no client in the class diagram, the client in this pattern has to be very specific in making a request. The request must be to the Context for a ConcreteStrategy. What does that look like in ActionScript 3.0? The following implementation shows how:
1 2 3 4 5 6 7 8 9 10 11 | package { import flash.display.Sprite; public class Client extends Sprite { private var gps:Context=new Context(new StratGPS()); private var map:Context=new Context(new StratMap()); private var compass:Context=new Context(new StratCompass()); } } |
In order to make a request through the Context participant for a specific ConcreteStrategy, all I had to do was to instantiate the ConcreteStrategy in the Context class’ constructor. Because the parameter in the Context constructor function is typed as the interface, I was able to specify any of the objects that implemented the interface—that includes all of the ConcreteStrategy classes. As you can see, they were all implemented.
Your Turn to Jump In!
This series requires reader participation, or it’s just not worth it. So, please try the following:
- Add a new ConcreteStrategy
- Test it using the Client class
- Send it in to the comments section of this blog
In this way I can get some feedback for the rest of the series, but I’m not going to continue the series if no one is interested. It is designed to help you understand how to implement your own design patterns and to see their value. So please help me out here and let’s see some of your ConcreteStrategies and let me know your experience with them.
Then we’ll continue with the series.
Related posts:

Bill Sanders
Hi Bill,
I got a question. One thing I never quite understood is the following: I know its GoF and all but why do we need something like a context here? In your example the implemented algorithm is called by some mediator context, but still, the client decides which strategy gets selected and therefore has to know them as well. In your example the client may not depend on the name of the implemented algorithm which seems to decouple things a bit again, but on the other hand it seems odd to me to instantiate a new object every now and then (or better permanently) just to get an inner algorithm of some other object executed. Because that’s what’s happening if you drive with a gps, the job isn’t done with just one executed strategy. So why not either show the strategy’s algorithm through the context’s interface or better, why not instantiating the strategies directly and calling their action when needed?
Many thanks
Lukas
Hi Lukas,
Well, I blame it on the Swiss–after all, Gamma wrote his Ph.D. dissertation at a Swiss university! ; )
Actually, what you’re asking is very important and gets to the core of the whole pattern. In fact it’s one I’ve asked myself,
The short answer is that it promotes loose coupling between the Client and the concrete strategy, and it helps maintain encapsulation in the concrete strategies. As such the Context class acts like an interface between the Client and ConcreteStrategy.
I hope to address your points more throughly in this series of posts as we delve deeper into the Strategy pattern. What we have at this point in time is an example that simply illustrates how the participants work together. Further on and with more concrete examples I hope to better address your excellent points.
(By the way…did you do a concrete strategy you wanted to send in?)
Kindest regards,
Bill
Ok I see. Let’s be patient. I really appreciate this approach of yours, because the real world use of dp’s is proved by any means but sometimes some parts just seem to be a waste of code, at least to me. This is just one example.
I don’t get the “implement your own strategy” point, as there’s only trace statements that make the difference so far. But still, I’d like to contribute as much as possible, so I invented the following strategy:
Hope that fits your needs.
Regards
Lukas
Lukas,
Best navigation algorithm ever!!!
Thanks and thanks for having some fun with it,
Bill
Hello hello!
Nice saturation so far. I still think that Strategy DP is so simple and obvious that it’s easy for beginners to think “This is to simple to be true. I must be doing something wrong…”… at least it happened to me.
As for the Context being a not-so-useful class, I think it’s just a matter the example which is just so simple and minimalistic that it’s hard to demonstrate how the Strategy is good. I took the liberty to put in some more beef into the example. My goal was to create a clearer separation of responsibilities between the Context and the Strategy. I hope it helps!
Cheers!
============ AS3 CODE ============
Hi Memo (whoops…that Spanish….er) Bill,
That was great. Thanks for sending it in. As you will see, the water gets deeper and deeper with the Strategy pattern, but I agree with you that the general concept is pretty clear.
Yes, my example starts off very simple Context, and unlike the Context in the State pattern, which is more complex but easier to understand, the Context in the Strategy pattern is quite subtle, but important.
Kindest regards,
Bill