Final runtime flexibility and future proofing; part 3 of GOF
Behavioural Patterns with C#
BarryMossman<is_at>primos.com.au
This is my fifth, and final, article looking at the GOF Design
patterns. Earlier articles studied the Creational Patterns,
Structural Patterns and began examination of the Behavioural
Patterns. This one looks at the final Behavioural Patterns. There are
links to my earlier articles at the bottom of
this one. This articles covers the following patterns:
The source for this article's demonstration
program is available at CodeCentral. See the link
at the bottom of this document.
The first article (Creational Patterns) also gave an overview of
where the patterns came from, and the general discussion of the
general techniques that they promoted. I will firstly briefly recap a
few of the points from that article.
The GOF design patterns help address the following challenges :
design ready to accommodate change & growth
design flexible systems that come ready to handle
reconfiguration and run time tailoring
code in manner to facilitate reuse during the development
and extension phases ... ie. both external and internal reuse, so
that we are rewarded by efficiencies as the project progresses,
coming for investments made earlier in the project.
implement change in a way that doesn't overly shorten the
system's useful lifespan
In a multi-person project the design patterns have the additional
utility of providing a shorthand language with which to describe
design options and specifications.
The design patterns were defined in the programming classic
entitled "Design Patterns" by Gamma, Helm, Johnson &
Vlissides. The four authors are commonly described as the Gang Of
Four (GOF) for brevity. The subtitle of the book is "elements of
reusable object-oriented software". There is a link to this
book at the end of this document.
One of the book's key points is that the authors favour using
"object composition" over "class inheritance"
when designing our system's objects. This means that our objects are
assembled at runtime from a number of helper classes working together
to deliver the desired behaviour, rather than being statically
defined at compile time using class inheritance. Objects that are
created in this way offer a great deal of runtime flexibility, and
are better set up for future modification. A general theme of the
Behavioural patterns is that they allow the composition of larger and
more flexible structures from smaller helper classes.
The approach necessitates more physical classes, but is made more
workable where patterns are used as they help to bring an
understandable structure to the design. The fact that the patterns
are based upon system design structures that have been tested and
refined over time is also of assistance.
Note that the advice is to only to "favour"
object composition over class inheritance, not to stop using
inheritance altogether. The two techniques work well together
A summary of the patterns
|
Pattern Name |
General Objective |
|
State |
This pattern is applicable for objects that need to be able to
change between various states, and where the object needs to have
differing behaviours for the different states. |
|
Strategy |
This pattern allows us to encapsulate algorithms as classes in
order to make them reusable, interchangeable or just hidden from
the client.
Use of this pattern can help achieve the goal of having an
application comprised of loosely coupled interchangeable parts,
avoiding an overly monolithic implementation of our application.
The pattern can help to reduce the amount of subclassing
required in some circumstances. |
|
Template |
The Template pattern permits us to offer flexibility and
achieve reuse within application algorithms, while still being
able to retain control over those elements of the algorithm which
we want to run unchanged.
The pattern is related to the Strategy pattern. Where the
Strategy pattern used delegation to vary the whole algorithm, the
Template pattern allows inheritance to specify variation to
portions of a flexible base algorithm |
|
Visitor |
In this pattern we design a class, or group of classes, to be
independent of the operations that will be performed upon it. The
operations are collected together into a separate Visitor class,
and the target classes (Elements) are designed to be "visitor
ready”.
Use of this pattern can reduce the impact of future system
changes, and can aid with source code organisation by having
common types of Operation grouped together within the Visitor
class. |
|
|
The following Behavioural Patterns have already
been covered in an earlier article (see link
at bottom of this article) |
|
Pattern Name |
General Objective |
|
Chain of Responsibility |
Allows us to decouple a client's request for action, from the
class that will implement it.
The client builds a chain of candidate classes (Handlers) to
handle the request, and then passes the request to the chain. The
client is simplified as it does not need to know which class will
finally handle the request. The request is passed down the chain,
one handler at a time, until one of them accepts responsibility
for the request.
There is much flexibility as the chain is built at runtime,
and the sequence can therefore be tailored by runtime or
configuration conditions. |
|
Command |
Allows us to make commands, or requests against an object,
into objects themselves.
Potential OO benefits include grouping of command series into
macros, providing undo support, facilitating command logging,
persisting commands or macros via Save|Restore, queuing commands
for later execution, and runtime tailoring of commands that are
to be executed. |
|
Interpreter |
This pattern enables us to design a script language, it's
syntax, and then implement an Interpreter to process requests
that have been recorded in that language.
This allows us to create a flexible client that is capable of
receiving and actioning high level request scripts written in a
command language that we have designed to suit the users of our
system. |
|
Iterator |
Outsource the task of iteration through an aggregate members
into a separate class.
Allows generic navigation code able to address different
aggregate classes. Client can open
simultaneous independent cursors into a single aggregate
instance, or an aggregate class can offer alternate methods of
navigation without cluttering it's implementation or public
interface. |
|
Mediator |
Collect the rules of interaction between a number of classes
(Colleagues), and encapsulate them into a separate Mediator
class.
Simplify our application's big picture since the cooperation
of the Colleague classes is collected together into the one
place.
Can facilitate more reuse, and reduce the disruption caused by
future enhancement. For example a new class of Mediator reusing
Colleagues working together in a new way, or new Colleagues which
could be coordinated in a familiar fashion by an old Mediator
class. |
|
Observer |
This pattern allows a number of Observer classes to observe,
and synchronize themselves to, the state of a Subject class.
Allows cohesion without tight coupling. Enables independent
reuse, or enhancement of, Subjects or Observers.
Introduces flexibility as Observers can be added or removed at
runtime, or subsequent versions could introduce new Observer
classes with minimal disruption. |
|
Memento |
This pattern allows us to save, or restore, an object's
internal state without violating it's encapsulation.
Addresses security considerations regarding information held
within the Momento, also may deployed such that only the object
that created the Momento can use it for restoration.. |
State Pattern
This pattern is applicable in a situation where our application
needs a class whose objects can change between various States (eg
between Open, Closed, Readonly etc), and the object's behaviour is
determined by it's current state. The pattern provides a means of
catering for the differing state behaviours using polymorphism rather
than using messy switch or if/else blocks everywhere throughout the
program.
The class, that needs the differing state behaviours, is called
the Context. It's state-dependant behaviours are provided by a
behind-the-scenes State class.
Benefits of the State pattern:
behaviour for any specific state is collected together, and
can be understood without having to search through the whole class
looking for "switch" and "if" logic blocks.
it should be easier to introduce a new state later, than in a
situation where state dependant behaviour logic was wide spread
the Context's state is "atomic", ie. it can never
have an invalid internal state, as could occur if the transition
from one state to another involved more than flicking a single flag.
There are some deployment options with the State pattern:
the State objects could be created as Singletons. Suitable if
the Context objects will be changing state frequently. The State
classes would need to provide only logic, ie. have no state of their
own as they would be shared if there were multiple Context objects
in operation at the one time. (see coverage of Singleton's in the
Creational Patterns article in the links section
at the bottom of this article).
The Context object can be responsible for switching between
states. ...Decouples the state classes from each other.
Or we can make the helper State objects responsible for
detecting the need for a state change, and for determining which
state to switch to next. Will make it easier to add further states
later.
In my demonstration program's we need to imagine that the Context
objects are describing sa vehicle which is used to transport some
kind of material. A Context object (vehicle) is in any one of the
following states:
Loading : At the Loading Dock.
Unloading : At the Unloading Dock, not fully unloaded yet.
Empty : Still at the Unloading Dock, but now empty
Repairing : At the Repair Shop.
Intransit : Intransit between the Loading, Unloading or
Repair areas.

The preceeding State diagram was produced by the free tool called
UMLet (see link at the bottom of this article).
In this example we can best see the State pattern's deliverables
by looking at the Context's Despatch method. The client uses this
method to cause the context to enter the Intransit state, however the
behaviour of this method needs to change depending upon the current
Context object's current state:
Loading : Despatch not allowed if the object has no load,
unless the Context is flagged for repair. By default Despatch will
cause the context to go Intransit heading towards Unloading, however
if the Context has been flagged for repair, and has no load,
it will go Intransit heading towards to Repairing.
Unloading : Despatch not allowed until the Context enters the
Empty state.
Empty : Can be Despatched. Will go to Intransit towards
Loading unless the Context is flagged for repair, in which case it
will go towards Repairing.
Repairing : Despatch only allowed if repair is complete. Will
go to Unloading.
Intransit : Despatch disallowed.
The State pattern handles this kind of requirement via
polymorphism. Each concrete helper State class would override the
Despatch method to provide behaviour appropriate to the Context's
current state. The pattern has made it easy to see an overview of the
Context's behaviour when it is a specific state. For example, in my
demonstration program we will be able to see that the Loading state
allows the Load method, and that it also allows it's own version of
the Despatch method. We would be able to easily see that the
Repairing state also allows the Despatch method, but with different
rules. The Repairing state doesn't have the Loading method, but it
does have a method to record that the repair job is complete. ...
This overview picture would have been obscured if we had implemented
this application requirement without the State pattern, as a State's
behaviour would become the sum of a series of switch and if blocks
spread throughout the Context class.
The State pattern should make it easy to introduce a new status
named FULL at some time in the future. The Empty status could be used
to show that the Context has completed Loading and is ready for
Despatch. We would only need to change the Load State to monitor
whether the Context was full, just as we determine whether it is
empty. We would probably modify the Load Status's Despatch method so
that it could no longer access the Despatch method, as this would be
deferred to the new Empty state. ... Thanks to the State pattern we
haven't had to search through the whole Context class looking things
that may be affected by this new state that we are introducing.
My implementation of the State pattern uses the deployment options
to use shareable singleton State objects, and to outsource the need
for triggering of state changes to the State classes themselves.
Here is the output from my demonstration run:

The client uses two service methods to display the Context's
status for the purposes of demonstration:
private void ShowStatus1(Context aContext, RichTextBox testOutput) {
testOutput.AppendText(String.Format(
"nStatus = {1}: Content = {0}, Repair requested ? = {2}n",
aContext.AmountLoaded, aContext.CurrentState.ToString(),
aContext.NeedsRepair));
}
private void ShowStatus2(Context aContext, int aUnLoadRequest,
int aUnloadAchieved, RichTextBox testOutput) {
testOutput.AppendText(String.Format(
"nStatus = {1}; Requested {2}, given {3}, Content now = {0}.n",
aContext.AmountLoaded, aContext.CurrentState.ToString(),
aUnLoadRequest, aUnloadAchieved));
}
The client code is as follows. Notice that the calls to the Despatch
method: have no arguments, the differing behaviour is coming from
polymorphism.
Context context = new Context();
// Load 80 units, then display status.
ShowUserCommentary(1);
context.Load(80);
ShowStatus1(context, listBox1);
/* Despatch loaded object, then display it's changed status
(= Intransit) */
ShowUserCommentary(2);
context.Despatch();
ShowStatus1(context, listBox1);
// Receive the loaded object, then unload 30 units and display status
ShowUserCommentary(3);
context.Arrival();
int unloadRequest = 30;
int unloadAchieved = context.Unload(unloadRequest);
ShowStatus2(context, unloadRequest, unloadAchieved, listBox1);
/* Attempt to despatch the object. Will fail as the Despatch
operation is not valid while the object is in the UNLOADING state.*/
ShowUserCommentary(4);
try {
context.Despatch();
}
catch (ApplicationException ex) {
listBox1.AppendText(String.Format(
"nException raised: {0}n",ex.Message));
}
/* try and unload a further 70 unit, receive just the 50 remaining.
The object is now empty, causing it's state to change to EMPTY */
ShowUserCommentary(5);
unloadRequest = 70;
unloadAchieved = context.Unload(unloadRequest);
ShowStatus2(context, unloadRequest, unloadAchieved, listBox1);
/* Despatch is now allowed. Process it's Arrival. We will be in
Loading state again. */
ShowUserCommentary(6);
context.Despatch();
context.Arrival();
ShowStatus1(context, listBox1);
/* Flag the need for repair. Despatch the object. This time It will
be routed to the Repair Shop, if it there were any loaded contents
it would have gone to the Unloading bay first. */
ShowUserCommentary(7);
context.RequestRepair();
context.Despatch();
context.Arrival();
ShowStatus1(context, listBox1);
Now to the pattern implementation. Firstly we shall define a couple
of enumerations to use as switch settings. One enumeration describes
the possible states for a Context object, and the other describes the
list of possible despatch destinations.
public enum State{Loading, Unloading, Empty, Repairing, Intransit}
internal enum Destination{None, Loading, Unloading, Repairing}
Then we shall look at the base class for the State helper classes. It
is an abstract class which provides method signatures for the Context
to use internally for all of the state dependant methods such as Load
and Despatch. It is also provides the behaviour that will be used if
the client tries to use a method that is not supported by the
Context's current State; in the case of my demonstration I just throw
an exception.
/* ================================
Base class for the Context's States
================================ */
abstract public class StateBase {
// fields
// properties
abstract public State OurState {get;}
// constructors
protected StateBase () {}
// methods
/* The Context's state dependant behaviour is implemented by our
sub-classes. If a sub-class does not override one of the following
methods this means that State of the Context class that the sub-class
represents does not support the method. We therefore throw an
exception as the attempt to use a method that is unsupported by the
state is a bug. */
virtual internal bool Despatch(Context aContext,
ref Destination aDestination) {
InvalidCallForState("Despatch");
return false; // just to keep compiler happy
}
virtual internal void Arrival(Context aContext,
ref Destination aDestination) {
InvalidCallForState("Arrival");
}
virtual internal bool Load(int aLoadQuantity,
Context aContext, ref int aCurrentLoad) {
InvalidCallForState("Load");
return false; // just to keep compiler happy
}
virtual internal int Unload(int aQuantityRequested,
Context aContext, ref int aCurrentLoad) {
InvalidCallForState("Unload");
return 0; // just to keep compiler happy
}
virtual internal void RepairCompleted(ref bool aRepairFlag) {
InvalidCallForState("RepairCompleted");
}
private void InvalidCallForState(string aCallName) {
throw new ApplicationException(
String.Format("{0} method not supported when Context in {1}",
aCallName,this.ToString()));
}
}
There will be singleton concrete State classes for each of the
Context's states as we shall see later, but firstly let us look at
how the State helper classes are going to be used within the Context
class. Here are the relevant sections from within the Context type.
We can see that it's current state is recorded by a private field
that will reference the singleton instance of one of the concrete
State classes. The Context's constructor initialises the context to
being in "Loading" state. Then finally there are the
public signatures for the methods whose behaviour is state dependant.
Each of these methods will utilise methods belonging to the State
helper object that is referenced by the private field mentioned
above.
// fields
/* the _state field determines the Context object's state. It refers
to a singleton instance of one of the StateBase's concrete
sub-classes. These classes implement state-dependant behaviour. */
private StateBase _state;
// constructors
public Context() {
/* set initial state to "Loading". There is a singleton instance for
each of the possible states. */
_state = Loading.Instance;
}
// methods
/* ------- The following group of methods have state dependant
implementations. The implementation is within concrete
sub-classes of the Statebase type ------------------ */
public bool Load(int aLoadQuantity) {
return _state.Load(aLoadQuantity, this, ref _amountLoaded);
}
public int Unload(int aQuantityrequested) {
return _state.Unload(aQuantityrequested, this, ref _amountLoaded);
}
public bool Despatch() {
return _state.Despatch(this, ref _destination);
}
public void Arrival() {
_state.Arrival(this, ref _destination);
}
public void RepairCompleted() {
_state.RepairCompleted(ref _needsRepair);
}
Here is the remainder of the Context class. I have snipped out the
members that we have just covered above. The majority of this code is
just related to my demonstration, rather than being part of the State
pattern. The exception is the ChangeState method. My demonstration
illustration of the State pattern uses the deployment option where
the helper State objects are responsible for detecting the need for a
state change, and for determining which state to switch to. Our
current state's helper object (referred to by the _state field) will
use this method if it determines that we need to change state.
public class Context {
// fields
private int _amountLoaded;
private bool _needsRepair = false;
private Destination _destination = Destination.None;
// properties
public int AmountLoaded {
get {return _amountLoaded;}
}
public bool NeedsRepair {
get {return _needsRepair;}
}
public State CurrentState {
get {return _state.OurState;}
}
// methods
public void RequestRepair() {
_needsRepair = true;
}
/* Method used to cause a transition from one Context state to another.
The need for state transition is detected is detected by the
State helper object pointed to by the _state field. It is that
State helper object that calls this method. */
internal void ChangeState(State aNextState) {
switch (aNextState) {
case State.Unloading:
_state = Unloading.Instance;
break;
case State.Intransit:
if (_destination == Destination.None)
throw new ApplicationException(
"Despatch called without a valid Destination.");
_state = Intransit.Instance;
break;
case State.Loading:
_state = Loading.Instance;
break;
case State.Empty:
_state = Empty.Instance;
break;
case State.Repairing:
_state = Repairing.Instance;
break;
}
}
}
Finally we shall look at the concrete State classes. As mentioned
above I have implemented these using the Singleton pattern using the
technique that was described in my article upon the GOF's Creation
patterns (see links section at the bottom of
this article). Singleton objects are stateless and shareable.
This implementation will cause a single reusable, and shareable,
object to be created for each of the Context's states by the first
use of that state by our application instance. Any subsequent use of
that same state by the same, or any other Context object within the
application, will reuse and share the same State helper object. This
will mean that switching between states will be very efficient. Here
is part of the concrete class for the Loading state. The following
snippet shows the members that are associated with the Singleton
behaviour of the class.
/* ================================
Loading State (one of the possible states of the Context class)
================================ */
public class Loading: StateBase {
// fields
private static readonly Loading singletonLoading = new Loading();
// properties
public static Loading Instance {
get {return singletonLoading;}
}
public override State OurState {
get {return State.Loading;}
}
// constructors
private Loading() {} // private, so unavail for outside use.
}
Then there are the members for the Loading class that are associated
with my demonstration program. Since the helper class for each state
is shareable between Context objects, it can have no state of it's
own. It will need to refer back to the Context object that it is
assisting wherever it needs to deal with instance data.
From the Loading class's members following we can see that the
Loading state only supports the Despatch and Load methods. If the
client attempts to use any of the other state dependant methods the
base class will issue an exception as the base behaviour has not been
overridden by this concrete class. We can see from the following that
the Loading state's Despatch behaviour is to disallow the despatch of
empty vehicles unless they are flagged for repair. Vehicles are
dispatched back towards the Loading Bay, unless they are both flagged
for repair and empty.
// methods
override internal bool Despatch(Context aContext,
ref Destination aDestination) {
if ((aContext.AmountLoaded == 0) & (!aContext.NeedsRepair))
return false;
aDestination =
((aContext.NeedsRepair) & (aContext.AmountLoaded == 0)) ?
Destination.Repairing:
Destination.Unloading;
aContext.ChangeState(State.Intransit);
return true;
}
override internal bool Load(int aLoadQuantity,
Context aContext, ref int aCurrentLoad) {
if (aContext.NeedsRepair)
return false;
else {
aCurrentLoad += aLoadQuantity;
return true;
}
}
Here is the Unloading class. We can see that it does not support the
Despatch method at all. Despatch is not allowed until the context
enters the Empty state.
/* ================================
Unloading State (one of the possible states of the Context class)
================================ */
public class Unloading: StateBase {
// fields
private static readonly Unloading singletonUnloading = new Unloading();
// properties
public static Unloading Instance {
get {return singletonUnloading;}
}
public override State OurState {
get {return State.Unloading;}
}
// constructors
private Unloading() {} // private, so unavail for outside use.
// methods
override internal int Unload(int aQuantityRequested,
Context aContext, ref int aCurrentLoad) {
int retval;
if (aQuantityRequested < aCurrentLoad) {
aCurrentLoad -= aQuantityRequested;
retval = aQuantityRequested;
} else {
retval = aCurrentLoad;
aCurrentLoad = 0;
aContext.ChangeState(State.Empty);
}
return retval;
}
}
Finally here is the Empty state. We can see that the Dispatch method
is supported now, but it has different behaviour to that seen in the
Loading state. The destination is now the Loading bay, unless the
vehicle is in need of repair in which case it goes to the Repair
Shop.
/* ================================
Empty State (one of the possible states of the Context class)
================================ */
public class Empty: StateBase {
// fields
private static readonly Empty singletonEmpty = new Empty();
// properties
public static Empty Instance {
get {return singletonEmpty;}
}
public override State OurState {
get {return State.Empty;}
}
// constructors
private Empty() {} // private, so unavail for outside use.
// methods
override internal bool Despatch(Context aContext,
ref Destination aDestination) {
if (aContext.AmountLoaded != 0)
return false;
aDestination = (aContext.NeedsRepair)?
Destination.Repairing:
Destination.Loading;
aContext.ChangeState(State.Intransit);
return true;
}
}
I won't labour the point by showing the implementation of the
Repairing and Intransit states here, although they are in my
demonstration program if you wish to see them.
Strategy Pattern
This pattern allows us to encapsulate algorithms into classes in
order to make them reusable, interchangeable or just hidden from the
client. This helps us towards a goal of having an application
comprised of loosely coupled interchangeable parts, and to avoid an
overly monolithic implementation of our application.
An object (Context ) can be given a selection of helper objects
(Strategies) to achieve it's ends. The helper Strategy objects all
have the same interface, so the client can chose which helper class
it wants to use at runtime. The algorithm that is achieving some
aspect of the Context's behaviour is outsourced to the Strategy
object(s).
The Strategy pattern could be applicable in the following
situations:
we need differing versions of an algorithm dependant upon run
time or configuration conditions, and would like to avoid a lot of
switch or if/else blocks.
we need a number of related classes that just differ in some
aspects of their behaviour. We would save a lot of sub-classing if
we could just use a generic class, but plug in the strategy
applicable to the run time conditions
we have an algorithm that we want our context to use, but
would like it to be kept private from the context for some reason.
My demonstration program's illustration of the Strategy pattern
has a Context class which can examine a document, and return to us a
list of all the words that immediately follow any given word. The
Context class can choose between two strategies to achieve this; the
first involves searching through the whole document looking for the
chosen word, and the other strategy deploys a keyed search into a
hashtable. Here is the program's output.

Firstly let us get the task of obtaining the word list from the
document out of the way. This is not part of the Strategy pattern,
but we need some data to work with. I use .Net's regular expression
support to break the document into a collection of words after
stripping off miscellaneous punctuation characters. The words are
collected into a specialist MatchCollection class, with collection
entries of type Match. Here is a client method to complete this task:
/* Obtain some data to demonstrate with. The data will be the
collection of words found in a text file */
private MatchCollection GetSomeData() {
Regex regex = new Regex(
@"[^s.,""-()] # discard non-words
w* # capture words",
RegexOptions.IgnoreCase
| RegexOptions.Multiline
| RegexOptions.IgnorePatternWhitespace
);
workListBox = new RichTextBox();
const string fileName = "Flyweight words.rtf";
try {
workListBox.LoadFile(fileName);
}
catch (System.IO.FileNotFoundException e) {
throw new ApplicationException(String.Format
("File "{0}" is needed by this demonstration; {1}",
fileName, e.Message));
}
return regex.Matches(workListBox.Text);
}
Next we shall look at the client code that produces the above output.
Firstly we obtain some data, then create a Context object that will
use the "array" strategy in the first instance. We
analyse the document using this strategy, and then change strategies
to use the same client code to analyse the document with the
"hashtable" strategy. The "Load" method is
called for the new strategy because each strategy has it's own
version of the Load method. The service method named
"FindAndDisplayNeighbours" will be shown in the code
snippet following this one.
MatchCollection data = GetSomeData();
Context context = new Context(new ConcreteStrategyUseArray());
context.LoadData(data);
/* Analyse document to find the list of all words that
immediately follow the search word in the document that we
loaded into the context. */
ShowUserCommentary(1);
FindAndDisplayWordNeighbours(context,"Philippe");
FindAndDisplayWordNeighbours(context,"the");
/* Change to a different strategy. The above strategy searched
through an internal arraylist to find the neighbour words. This
new strategy uses keyed searches into a hashtable. */
ShowUserCommentary(2);
context.ChangeStrategy(new ConcreteStrategyUseHashtable());
context.LoadData(data);
FindAndDisplayWordNeighbours(context,"Philippe");
FindAndDisplayWordNeighbours(context,"the");
Finally for the client we shall look at the FindAndDisplayNeighbours
service method. The Context is asked for the list of "neighbouring"
words. The Context will use the currently selected strategy to
perform this task.
/* Get, and print, the list of single words that immediately follow
each occurrence of the search word in the document being analysed. */
private void FindAndDisplayWordNeighbours(Context aContext,
string aSearchWord) {
string[] neighbourList = aContext.GetNeighbours(aSearchWord);
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < neighbourList.Length ; i++)
{
sb.Append(neighbourList[i] + " ");
}
listBox1.AppendText(String.Format(
"nThe word "{0}" is immediately followed by the the following words; {1}",
aSearchWord, sb.ToString()));
}
Now to the pattern's implementation. The interface of the helper
Strategy objects can be seen by looking at their base class. We can
see that it is going to assist the Context with LoadData and
GetNeighbours services.
abstract public class StrategyBase {
// methods
abstract public void LoadData(MatchCollection aList);
abstract public string[] GetNeighbours(string aWord);
}
Next we shall look at the implementation of the Context class. We can
see that it maintains a reference to the Strategy object that is
currently helping it. Requests from the client are passed on to the
Strategy object.
public class Context {
// fields
private StrategyBase _strategy;
// constructors
public Context (StrategyBase strategy) {
_strategy = strategy;
}
// methods
public void ChangeStrategy(StrategyBase strategy) {
_strategy = strategy;
}
// Load the document into an internal form suitable for searching.
public void LoadData (MatchCollection aList) {
_strategy.LoadData(aList);
}
public string[] GetNeighbours(string aWord) {
return _strategy.GetNeighbours(aWord);
}
}
We don't need to study the concrete Strategy classes to understand
the Strategy pattern, but the demonstration doesn't do much without
them. This first strategy loads all the words from the document into
an arraylist, and then scans through the list to pluck out all of the
neighbours of the word being analysed.
public class ConcreteStrategyUseArray: StrategyBase {
// fields
private string[] _wordList, _neighbourList;
// methods
/* load document into structures suitable for a search to find
any given word's "neighbours".
Build two lists. one to contain all words (in lower case to
make matching easier, and the other to contain the word's
neighbour in the same relative array cell (case preserved). */
override public void LoadData (MatchCollection aList){
_wordList = new string[aList.Count];
_neighbourList = new string[aList.Count];
for (int i = 0; i < aList.Count; i++) {
_wordList[i] = (aList[i].ToString()).ToLower();
_neighbourList[i] = (i < (aList.Count-1))?
aList[i+1].ToString():"";
}
}
/* Return the list of all neighbours of the word passed by
parameter.*/
override public string[] GetNeighbours(string aWord) {
ArrayList workList = new ArrayList();
int i = 0;
int index = 0;
// look at whole document
do {
index = Array.IndexOf(_wordList, aWord.ToLower(), i);
if (index >= 0) {
workList.Add(_neighbourList[index]);
/* search will continue from beyond where
we have just found the target word. */
i = index + 1;
}
} while (index >= 0);
string[] retval = new string[workList.Count];
workList.CopyTo(retval);
return retval;
}
}
Finally we have the strategy that employs a hashtable collection. We
trade off a saving during the search phase, for a little more expense
during the Load phase.
public class ConcreteStrategyUseHashtable: StrategyBase {
// fields
/* This field contains each word found in the document up to,
but not including, the document's last word.
The key for the first occurrence of the word is the word
itself in lower case.
The value is a comma separated list of the word that immediately
follows each coinsurance of the word within the document.
eg. if the document is "The cat sat on the mat."
Key Value
---- -----
the cat,mat
cat sat
sat on
on the */
private Hashtable _neighbourList;
// methods
/* load document into a structure suitable for a search to find any
given word's "neighbours". */
override public void LoadData (MatchCollection aList){
_neighbourList = new Hashtable(aList.Count);
StringBuilder neighbourWork;
// process the whole document
for (int i = 0; i < aList.Count-1; i++) {
// word comparison is not case sensitive
string word = aList[i].ToString().ToLower();
/* detect whether the document has already used the word
being examined. */
if (_neighbourList.ContainsKey(word)) {
/* if so, then add the new neighbouring word
into a comma separated list with those
already recorded. */
neighbourWork = (StringBuilder)_neighbourList[word];
neighbourWork.AppendFormat
(",{0}", aList[i+1].ToString());
_neighbourList[word] = neighbourWork;
}
else
// record the new word's neighbouring word
_neighbourList.Add
(word, new StringBuilder(aList[i+1].ToString()));
}
}
// Return the list of all neighbours of the word passed by parameter.
override public string[] GetNeighbours(string aWord) {
string word = aWord.ToLower();
string neighbours = "";
/* get the comma separated list of neighbouring words if the
word being examined exists within the document. */
if (_neighbourList.ContainsKey(word)) {
StringBuilder neighbourList =
(StringBuilder)_neighbourList[word];
neighbours = neighbourList.ToString();
}
// return the list of neighbouring words in a string array.
return (neighbours.Split(new Char [] {','}));
}
Template Pattern
The Template pattern permits us to offer flexibility and achieve
reuse within application algorithms, while still being able to retain
tight control over those elements of the algorithm which we want to
run unchanged.
In this pattern we define a base class to define the structure of
an algorithm, while deferring some of the steps to concrete
subclasses which will inherit from the base. The pattern runs using
the "Hollywood principle" which is "Don't call us,
we'll call you". This is because the base class retains control,
as it calls subclass methods as required, rather than the usual
arrangement where concrete sub-classes call the ancestor's "base"
methods. We have therefore been able to ensure that some portions of
the algorithm are run without change. The pattern allows us to avoid
the bugs that could occur if an ancestor class neglected to call some
essential part of the base specification of the algorithm.
The base class provides for variability within the algorithm in
either of two ways:
The pattern is related to the Strategy pattern. Where the Strategy
pattern used delegation to vary the whole algorithm, the Template
pattern allows inheritance to specify variation to portions of a
flexible base algorithm.
My illustration of the Template pattern has a base algorithm which
produces a timestamped message. The concrete subclasses inherit from
the base algorithm, using it's basic structure and some of it's
methods. They are required to provide their own time stamp format,
and have the option of overriding a "hook" method that
sets the font format for any part of the message which is enclosed
within quotation marks.
Here is the illustration's client code:
/* Use our template to produce a message. Any part of the message
that is within quotation marks will be specially formatted,
and a timestamp will be provided. */
TemplateBase template = new ConcreteTemplate_1();
ShowUserCommentary(1);
listBox1.SelectedRtf = template.TemplateMethod(
@"Brought to you by the ""Template "" pattern");
// now use a variation upon the same algorithm to produce
// a slightly different message.
template = new ConcreteTemplate_2();
ShowUserCommentary(2);
listBox1.SelectedRtf = template.TemplateMethod(
@"Brought to you by the ""Template "" pattern");
It produces the following output.

The interface for our Template pattern's base class could be
described as follows, where TemplateMethod is the method called by
the client to invoke the algorithm, and the other two methods are
"primitive operations" that may be overridden by the
concrete subclass that inherit from the base. The remainder of the
algorithm is fixed, and will run as the original designer intended.
public interface ITemplate {
// template method; used by client
string TemplateMethod ();
// primitive methods; may be overridden by concrete sub-classes
string GetDateMessage();
void GetStyleForQuotes(out float aSize,
out FontStyle aStyle,
out Color aColor);
}
Here is the implementation of the base class. The TemplateMethod is
called by the client, and it drives the processing of the algorithm.
It uses the GetDateMessage which is abstract, and therefore must be
overridden by a concrete descendant to provide implementation. The
TemplateMethod also uses the GetFormatingForQuotes method which has a
default implementation, a concrete subclass may override this "hook
method" if it wants a different implementation to the default
one provided.
The algorithm parses a text string, and applies special formatting
to any text found enclosed within quotation marks. It then appends a
message timestamps, and passes the formatted string back to the
client.
// --- Base class
abstract public class TemplateBase {
// methods - template method; called by the client
public string TemplateMethod () {
float fontSize;
FontStyle fontStyle;
Color color;
GetStyleForQuotes(out fontSize, out fontStyle, out color);
string message = (@"Brought to you by the ""Template "" pattern"
+ @GetDateMessage());
return
FormatMessage(message, fontSize, fontStyle, color);
}
// methods - primitive methods; used by the template message
/* The first is an abstract method requiring an override
by the concrete sub-class. The second is a "hook"
method, which may, or may not be overridden */
abstract public string GetDateMessage();
virtual public void GetStyleForQuotes(out float aSize,
out FontStyle aStyle,
out Color aColor) {
aSize = 13;
aStyle = FontStyle.Italic;
aColor = Color.Blue;
}
// methods - other; service methods
/*
private string FormatMessage(string aMessage,
float afontSize,
FontStyle aFontStyle,
Color aColor) {
// create a richTextObject to format our message into RTF format
RichTextBox rich = new RichTextBox();
rich.SelectionColor = System.Drawing.Color.MediumBlue;
Color saveColor = rich.SelectionColor;
rich.AppendText("n");
/* Divide message text into sets of leading unquoted material,
following by material contained within quote marks. */
MatchCollection mc = BreakApartMessage(aMessage);
// format the message for the client
foreach (Match m in mc) {
GroupCollection gc = m.Groups;
if (gc["unquoted"].Length > 0) {
rich.SelectionColor = saveColor;
rich.AppendText(gc["unquoted"].Value);
}
int quotedLength = gc["quoted"].Length;
if (quotedLength > 0) {
rich.SelectionColor = aColor;
Font currentFont = rich.SelectionFont;
rich.SelectionFont = new Font(
currentFont.FontFamily,
afontSize,
aFontStyle);
rich.AppendText(gc["quoted"].ToString()
.Substring(0,(quotedLength-1)));
rich.SelectionColor = saveColor;
rich.SelectionFont = currentFont;
rich.AppendText(@"""");
}
}
return rich.Rtf;
}
/* Break the message into sets of leading unquoted text, and text
containing within quotation marks. */
private MatchCollection BreakApartMessage(string aMessage) {
Regex regex = new Regex(
@"(?<unquoted>[^""]*""?)? # Text leading up to, and
# including an opening quote
# mark if there is one.
(?<quoted>[^""]*""{1})? # Quoted text, and the closing
# quote mark. Include closing
# quote mark so we can don't
# capture all up to document
# end if there is an
# unmatchedquote mark.
",
RegexOptions.IgnoreCase
| RegexOptions.Multiline
| RegexOptions.IgnorePatternWhitespace
);
return regex.Matches(aMessage);
}
}
Finally here are the two concrete subclasses. The first provides an
override for the optional "hook" GetStyleForQuotes
method.
// --- Concrete sub-classes
public class ConcreteTemplate_1: TemplateBase {
// methods
// optional override of template's "hook" method
override public void GetStyleForQuotes(out float aSize,
out FontStyle aStyle,
out Color aColor) {
aSize = 20;
aStyle = FontStyle.Bold | FontStyle.Underline;
aColor = Color.Red;
}
// mandatory override of template's abstract method
override public string GetDateMessage() {
return String.Format(" upon this {0:U}",DateTime.Now);
}
}
public class ConcreteTemplate_2: TemplateBase {
// fields
private readonly DateTime _RutherfordPrize =
new System.DateTime (1908,12,11);
// methods
override public string GetDateMessage() {
return String.Format(" upon this day, just {0:N0} days since Ernest Rutherford was awarded the Nobel Prize for work done upon the structure of the atom.",
System.DateTime.Now.Subtract(_RutherfordPrize).Days);
}
}
Visitor Pattern
In this pattern we make a class independent of the operations that
can be performed upon it. The operations are then defined within
their own separate Visitor classes. The class, or classes, upon which
they can operate (Elements) are made "visitor ready" so
that they can accept the Visitors.
The Visitor pattern can provide the following benefits:
a new operation can be provided without having to change all
of the affected Element classes. All we need to do is create a new
Visitor class.
all of the program logic for a specific operation is gathered
together into it's own Visitor class, avoiding a situation where the
operation logic is spread across each of the individual Element
classes that the operation can affect.
The pattern is especially applicable in the following situations:
where the Element classes are beyond the control of the
Programmer who will be tasked with adding, or changing, operations
that will act upon the Element classes.
where the application will have multiple Element classes with
differing interfaces, and there is the need to perform the same
operations upon all of the Element objects, where the operation
algorithms need to be different due to the differences in Element
classes being operated upon.
where we can achieve code sharing or improved organisation of
our program logic, by gathering together the code required for an
operation that will be performed upon a diverse set of Element
classes.
where we expect that we will be more likely to add further,
or change existing, operations, than we will be to add further
Element classes to be operated upon.
A Visitor may operate upon a individual Element objects, or it may
operate upon a Composite collection of Element objects. The Visitor
may accumulate information, pertaining to the collection as a whole,
as it iterates through all of the member Elements. This is similar in
function to an Internal Iterator (see Iterator pattern in the links
below), however the Visitor pattern doesn't require that each of the
Element objects that it will navigate through share a common base
class or interface.
The Visitor pattern has a couple of potential problems:
we may be forced to compromise encapsulation, by needing to
expose too much of the Element class's internals to make the Element
classes "visitor ready"
it requires more source code changes if we need to add a new
Element class where there are a lot of Visitor classes that will be
required to operate upon it.
if overused it can increase undesirable coupling within our
application, versus a solution where we just used polymorphism; ie.
the Elements descend from an Abstract base class, and each Element
overriding the operation" methods.
I have two illustrations of the Visitor pattern:
the first example has two Element classes, and two Visitor
operations to act upon those Elements.
the second example shows a Visitor acting upon a composite
object containing a mixed collection of Element objects. It operates
upon the composite, and then provides statistics about the whole
collection.
Here is the client code to run the first illustration:
/* Construct two Element objects. They inherit from the same base
class, but are of different types. Their shared base class is
"visitor ready", and has a readonly Value property.
Set their Value property by their differing mechanisms to
the values "Borland" and "Switzerland". */
ElementBase element = new ConcreteElement_1("Borland");
ElementBase element2 = new ConcreteElement_2();
((ConcreteElement_2)element2).Name = "Switzerland";
ShowUserCommentary(1);
ShowContentsOfValueProperty(element.Value);
ShowContentsOfValueProperty(element2.Value);
/* Create 2 Visitor objects. One can cause the target Element's
Value property contents to be converted to upper case, and the
other can cause the characters in the properties contents to
become separated by the "_" character. */
VisitorBase vCapitalise = new ConcreteVistor_1();
VisitorBase vAddDashes = new ConcreteVistor_2();
/* Apply the one Visitor to the 1st Element, and both Visitors the
2nd Element. */
element.Accept(vAddDashes);
element2.Accept(vCapitalise);
element2.Accept(vAddDashes);
ShowUserCommentary(2);
ShowContentsOfValueProperty(element.Value);
ShowContentsOfValueProperty(element2.Value);
And this is the output:

The essential interface for the visitor pattern can be thought as
as:
// --- interfaces
public interface IElementBase {
void Accept(IVisitorbase v)
}
public interface IVisitorBase {
}
The Visitor is passed into the Element's Accept method. The concrete
Element class that receives the Accept method call will pass itself
into the method within the Visitor object that specifically handles
this flavour of Element concrete class as we are about to see. Here
is the definition of the base class for the Element classes. The
property is just something I need for the demonstration. The key
thing is the Accept method, which is what is making the Element
classes "visitor ready".
// --- Element; the objects that get acted upon by the Visitors
public abstract class ElementBase {
// fields
protected string _value;
// properties
public string Value {
get {return _value;}
}
// methods
// ... method to make the Element visitor-ready
abstract public void Accept(VisitorBase visitor);
}
Next we shall look at the concrete Element implementations. The key
part to focus upon is the overridden Accept methods. The incoming
Visitor will have a separate method for each concrete Element class.
The overridden Accept method calls the Visitor method that
specifically handles this operation for this specific concrete
Element class.
The other source code is just something to make the point that
each of the concrete classes can have differing interfaces and
mechanisms.
public class ConcreteElement_1: ElementBase {
// fields
protected string _text;
// properties
public string Text {
get {return _text;}
set {
_text = value;
_value = value;
}
}
// constructor
public ConcreteElement_1 (string aText) {
this.Text = aText;
}
// methods
override public void Accept(VisitorBase visitor) {
visitor.VisitElement_1(this);
}
}
public class ConcreteElement_2: ElementBase {
// fields
private string _name;
// properties
public string Name {
get {return _name;}
set {
_name = value;
_value = value;
}
}
// methods
override public void Accept(VisitorBase visitor) {
visitor.VisitElement_2(this);
}
}
Next the definition of a base class for the Visitor classes. We have
abstract method definitions for each concrete Element class so the
compiler can check for us that each Visitor has been configured to
handle all of the concrete Element classes.
// --- Visitors; objects that will act upon upon the Elements
public abstract class VisitorBase {
// methods
public abstract void VisitElement_1(ConcreteElement_1 element);
public abstract void VisitElement_2(ConcreteElement_2 element);
}
Finally we have the Concrete Visitors which do all of the work. As we
can see the pattern relies up the fact that the Element classes have
exposed enough of their own state to allow the Visitor to achieve
it's objective. This exposure requirement can mean that the visitor
pattern is unsuitable for our application. This could occur if we
required so much exposure of the Element's internal state to the
point where we felt that the Element class's encapsulation had been
compromised.
public class ConcreteVistor_1 : VisitorBase {
// methods
override public void VisitElement_1(ConcreteElement_1 element) {
element.Text = element.Text.ToUpper();
}
override public void VisitElement_2(ConcreteElement_2 element) {
element.Name = element.Name.ToUpper();
}
}
public class ConcreteVistor_2 : VisitorBase {
// methods
override public void VisitElement_1(ConcreteElement_1 element) {
element.Text = FormatText(element.Text);
}
override public void VisitElement_2(ConcreteElement_2 element) {
element.Name = FormatText(element.Name);
}
private string FormatText(string aText) {
StringBuilder retval = new StringBuilder();
char[] arr;
arr = aText.ToCharArray();
foreach (char ch in arr) {
retval.Append(ch);
retval.Append('_');
}
if (retval.Length > 0) retval.Remove(retval.Length-1,1);
return retval.ToString();
}
}
Visitor pattern – second illustration
In the first illustration we looked at a Visitor being applied to
an individual object, this time we will look at the Visitor being
dappled to a composite collection of diverse Element types. When our
Visitor is acting upon a collection we have the option of
accumulating state within the Visitor while it navigates through all
the Elements in the collection as we will see in this example.
The collection itself is an implementation of the Composite
pattern. This pattern is covered in my article upon the GOF's
"Structural Patterns"; see link at
the bottom of this article.
In my illustration the concrete Elements classes are various types
of fruits. The collection is a fruit bowl that can contain a number
of pieces of various types of fruit. Each piece of fruit has a
designated weight. We have a "juice" operation that will
convert the bowl of fruit into fruit juice. Each fruit type
has an assumed percentage juice yield based upon the amount of juice
to be expected from a piece of fruit of that type. The weight of
juice that is expected from the fruit bowl is therefore determined by
the fruit types, and the individual weights of the pieces of fruit.
Here is the snippet of client code, and the private method that it
uses to display the results:
/* Try a different implementation. This time we have a
Composite class to contain a collection of Element
classes. The Elements are fruit of various types
and weights. */
FruitCollection fruitBowl = new FruitCollection();
fruitBowl.Add(new Apple(1.2f));
fruitBowl.Add(new Orange(1.4f));
fruitBowl.Add(new Apple(1.0f));
/* Create a Visitor. It converts the fruit to juice, and
calculates the accumulated juice yield (weight) for
fruit objects that it operates upon. Differing fruit
types may have differing yield percentages. The point
is to show a visitor acting upon a collection, and
accumulating state during it's journey. */
ShowUserCommentary(3);
Juice juice = new Juice();
/* Apply the visitor to the collection; convert the fruit bowl
into juice. */.
fruitBowl.Accept(juice);
ShowJuiceStatistics(juice);
/* Add another Element to the collection, reapply the Visitor
to get a different result. */
ShowUserCommentary(4);
fruitBowl.Add(new Orange(0.8f));
juice.Reset();
fruitBowl.Accept(juice);
ShowJuiceStatistics(juice);
}
private void ShowJuiceStatistics(Juice juiceVisitor) {
listBox1.AppendText(String.Format(
"n Juice yield weight is {0:0.#}",
juiceVisitor.YieldWeight));
listBox1.AppendText(String.Format(
"n Percentage apple juice = {0:0.#}",
juiceVisitor.PercentageApple));
}
Here is the output:

Here is the implementation of the base class for the fruit
Elements. The pattern doesn't require that our Element classes share
a common base class, although I have one in this illustration. The
pattern only requires that the Element classes implement an interface
containing the Accept method.
// --- Base class for the "Element" class in the pattern
abstract public class FruitBase {
// fields
private float _weight;
// properties
public float Weight {
get {return _weight;}
}
// constructor
public FruitBase(float aWeight) {
_weight = aWeight;
}
// methods
// ... method to make the Element visitor-ready
abstract public void Accept(Juice visitor);
public void ResetWeight() {
_weight = 0;
}
}
Next is the implementation of the Composite class for the bowl of
fruit. As you can see it implements it's own "Accept"
method, which iterates through the collection's member Elements, and
calling the Accept method for each.
// --- Collection of the "Element" objects
public class FruitCollection {
// fields
private ArrayList _collection = new ArrayList();
// methods
public void Add(FruitBase aFruit) {
_collection.Add(aFruit);
}
public void Remove(FruitBase aFruit) {
_collection.Remove(aFruit);
}
public void Accept(Juice visitor) {
foreach (FruitBase fruit in _collection) {
fruit.Accept(visitor);
}
}
}
Next the concrete Element classes:
// --- Concrete "Element" classes
public class Apple: FruitBase {
// constructor
public Apple(float aWeight) :base(aWeight) {
}
// methods
override public void Accept(Juice visitor) {
visitor.VisitApple(this);
}
}
public class Orange: FruitBase {
// constructor
public Orange(float aWeight) :base(aWeight) {
}
// methods
override public void Accept(Juice visitor) {
visitor.VisitOrange(this);
}
}
Finally the implementation of the Visitor class. It contains the
"juice" methods for each Element class type, and also the
mechanisms for accumulating and returning state values.
// --- Concrete "Visitor" class
public class Juice {
// fields
protected float _weightApples, _weightOranges;
// properties
public float PercentageApple {
get {return
(_weightApples * 100)/(_weightApples + _weightOranges) ;}
}
public float YieldWeight {
get {return (_weightApples + _weightOranges) ;}
}
// methods
public void VisitApple(Apple fruit) {
_weightApples += fruit.Weight * .85f;
}
public void VisitOrange(Orange fruit) {
_weightOranges +=
fruit.Weight * .75f; // thick skin, less yield
}
public void Reset() {
_weightApples = 0;
_weightOranges = 0;
}
}
Conclusion
This article has continued examination of the
Behavioural Patterns described by the GOF in their book titled
"Design patterns". I think that the study of the design
patterns is a worthwhile thing to do. I found the following links
useful while studying the patterns myself and while preparing this
article. The book itself is a good investment as it provides
supplementary detail upon the problems that the patterns are trying
to solve, the elements of the solution, and the consequences and
trade-off's involved in using the patterns.
This completes my series of articles looking at the Design
Patterns. I hope that you have found the articles helpful, and I wish
you good luck with your system design adventures !
Links