Runtime flexibility and future proofing; GOF Behavioural Patterns
with C# - Part 2
BarryMossman<at>primos.com.au
This is my fourth article looking at the GOF Design patterns. The
earlier articles studied the Creational and Structural Patterns, and
looked at the first few Behavioural Patterns. There are links
to my earlier articles at the bottom of this one.
There was so much material within the Behavioural patterns that I
have spread these across three articles. The Behavioural Patterns
are:
patterns covered in this article:
patterns already covered in an earlier article:
patterns deferred until my final article in this series:
The source for this article's demonstration
program is available at CodeCentral. See the link
at the bottom of this document The program contains annotated
example displays, and also displays some notes about the patterns, so
if you are interested in starting to work with the patterns it may be
a useful utility to have on your desktop during the learning period.
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 and levity. 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 |
|
Iterator |
Outsource, into a separate class, the task of iteration
through an aggregate's members.
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.
An "internal" iterator can be created, allowing
the client to ask the aggregate to step through itself applying a
passed invocation list of methods against each of the aggregate's
members. |
|
Mediator |
Collect the rules of interaction between a number of classes
(Colleagues), and encapsulate them into a separate Mediator
class.
Clarify 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. |
|
Momento |
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 be deployed such that only the
object that created the Momento can use it for restoration.. |
|
|
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 Pattern
This pattern allows our client program to step sequentially
through the members within an aggregate object without comprising the
aggregate's encapsulation, as it removes any requirement that our
client have knowledge of the aggregate's internal composition.
Use of the iterator pattern allows our client to be written such
that we can switch concrete aggregate classes without requiring any
modification to the client's navigation code. This can facilitate run
time flexibility, and can reduce the cost of future application
maintenance.
Our client could have multiple simultaneous independent cursors
into the one aggregate instance, perhaps using differing sort or
filtering criteria.
Use of the pattern can also lighten both our client and aggregate
classes, as neither need to implement the code necessary for
navigation through the aggregate. In a case where there are multiple
possible modes of navigation the run time burden will be lightened as
we will only need to instantiate those paths that are actually in
use. We could also develop a polymorphic iterator which is suitable
for use with more than one aggregate class.
The pattern is usually used as follows:
the client instantiates an aggregate object
the client asks the aggregate object to create an instance of
a suitable Iterator class via a Factory method (see Creational
patterns). This step is important as we will want to shield our
client from the actual class name of the Iterator so that our logic
will not need to be changed if we modify things to use a different
Iterator class, or use a different aggregate class having a
different Iterator.
If our aggregate class implements the IEnumerable interface
we can make implicit use of an Iterator without explicitly
requesting one. My demonstration illustrates this.
the Iterator class contains the navigation functionality, and
maintains it's own cursor position. We can therefore have multiple
Iterator instances active at the one time for the one aggregate
instance, each maintaining it's own positioning.
there are two classes of Iterator (both demonstrated in the
demo program):
My demonstration program will illustrate each of these points.
The dotNet framework makes it very easy for us to implement basic
use of an External Iterator pattern as there is much in-built support
for collection iteration via the IEnumerable and IEnumerator
interfaces.
IEnumerator is the interface for the Iterator class, and has
the methods necessary for navigation through the aggregate. The
minimum functionality required are methods MoveNext and Reset, and a
Current property which returns the current member as an object. The
Reset method sets the cursor to it's initial position which is just
prior to the first member element.
IEnumerable is the interface used by the aggregate class, and
contains a factory method called GetEnumerator which returns an
instance of an iterator for use with the aggregate.
Support for these interfaces is in-built into arrays, the various
collection classes, and the GUI components which contain collections.
My demonstration program makes some use of this in-built
functionality.
We can also implement our own Iterators, maybe to provide
alternate sequences, filtering, or extended functionality such as
Previous and SkipTo. My Demonstration program includes an example of
this also.
Now let us look at my demo program. Firstly we will create a
generic routine to iterate through our aggregate classes, so that it
easy to see that generic code is being used for iteration. The
compiler will allow the foreach command to be used if the agregate
type that it is being used over implements the IEnumerable interface
with it's GetEnumerator method, and if the the returned iterator
implements the methods in the IEnumerator interface.
// Generic code to iterate through either of our aggregate classes.
private void IterateAndPrint(IAggregate aCollection, RichTextBox testOutput) {
foreach (int i in aCollection) {
listBox1.AppendText(String.Format("n Element={0}",
i.ToString()));
}
}
Now some client code to call the above generic method. You will
notice that I build the aggregate, and then just use the generic
method to step through it, without creating or referring to an
Iterator at all. This is possible because of the iterator pattern
support that is built into the dotNet framework. The framework will
notice that my Aggregate class has implemented the IEnumerable
interface, and seeing use of the foreach verb will automatically
cause creation of the aggregate's iterator object.
(Note: things will get even better when we look at this
implementation of the pattern as you will discover that I haven't had
to write any code for the Iterator class at all, but instead have
just surfaced dotNet's inbuilt iterator.)
/* Firstly create an instance of our aggregate class, then iterate
through it's members using it's associated Iterator. dotNet makes
things easy for us. Since the aggregate class implements the
IEnumerable interface we can use the foreach instruction. The
Iterator object is used implicitly so we don't need to instantiate
it ourself. */
ShowUserCommentary(1);
IAggregate aggSmall = new ConcreteAggregate1();
aggSmall.Add(1);
aggSmall.Add(2);
IterateAndPrint(aggSmall,listBox1);
To further explore the Iterator pattern, the next client snippet
builds another aggregate object from a different class, then iterates
through the collection members using the old generic client code. We
shall soon see that the behind the scenes basis of the first
aggregate class was an arraylist, and this second aggregate class
employs an array. We are able to iterate through either generically.
This time I have implemented my own iterator rather than just
surfacing the default one supplied by the dotNet framework. Since it
is my own iterator I can change the sequence or selection of members
returned by the iteration. In this case I return the members in
reverse sequence.
/* Now create an instance of another aggregate class (this one is
internally implemented with arrays, where as the other used
ArrayLists). Iterate through this new object using the same
generic code.
The above example made implicit use of the Iterator object that
is in-built into the dotNet framework. This example uses an
Iterator that i have built. It presents that data in reverse
sequence. The compiler will see that our class implements the
IEnumerable interface, and will allow use to use the foreach
command even though we are not using dotNet's inbuilt iterator
support. */
ShowUserCommentary(2);
IAggregate aggBig = new ConcreteAggregate2(3);
aggBig.Add(100);
aggBig.Add(200);
aggBig.Add(300);
IterateAndPrint(aggBig,listBox1);
Finally we shall illustrate the use of two iterators over a single
aggregate object allowing our client to have multiple independent
cursors. This snippet also illustrates explicit use of the iterator's
public members rather than leaving all the navigation to the foreach
instruction.
/* We will now use two iterators at the same time on the one
aggregate to illustrate that the Iterator pattern that it is also
useful to allow multiple cursors into the one object. This time
we will navigate with one of the Iterators ourself, rather than
using the foreach command. */
ShowUserCommentary(3);
IEnumerator iterator = aggBig.GetEnumerator(); // create the Iterator
foreach (int i in aggBig) {
listBox1.AppendText(String.Format(
"n Outer Loop: Element={0}",i.ToString()));
iterator.Reset();
while (iterator.MoveNext()) {
listBox1.AppendText(String.Format(
"n .. Inner Loop:Element={0}",
iterator.Current.ToString()));
}
}
Here is the output from the above steps. As with all of my examples,
the text with the black font has been output by the
ShowUserCommentary method. I haven't listed in this article to save
space.

The basic public interface for the pattern could be described as:
public interface IEnumerator {
// properties
object Current {get;}
// methods
bool MoveNext();
void Reset();
}
public interface IEnumerable {
// methods
IEnumerator GetEnumerator();
}
Now to the pattern implementation. We will define an interface
(IAggregate) to extend dotNet's IEnumerable interface. The standard
IEnumerable interface contains the GetEnumerator method. We extend
this with an Add method that the client will use to Add new member
elements into an Aggregate.
// interfaces
public interface IAggregate: IEnumerable {
// methods
void Add(int aNewMember);
}
Then to my aggregate classes, each of which implements our IAggregate
interface.
I have based the first of these upon an ArrayList. The dotNet
framework has made it easy to implement the Iterator pattern as
Microsoft have already implemented the IEnumerable interface into
aggregate-type classes. I can obtain an iterator just by just asking
for one; ie. calling the ArrayList's GetEnumerator method.
public class ConcreteAggregate1: IAggregate {
// fields
ArrayList _dataCollection = new ArrayList();
// methods
public void Add(int aNewMember) {
_dataCollection.Add(aNewMember);
}
public IEnumerator GetEnumerator() {
return _dataCollection.GetEnumerator();
}
}
You can see a list of all the classes that implement IEnumerable
interface in the help text by looking up "IEnumerator",
then "About IEnumerable interface".
Now to the second aggregate class. This time I based the
collection upon an array. The array type also implements the
IEnumerable interface, so could have just asked for an inbuilt
iterator as above, but this time I wanted different iteration
behaviour. The standard iterator allows us to step through a
collection in a forwards direction. I want to step through the
collection in reverse sequence. I could have just sorted the array,
but since the intent is to illustrate the iterator pattern I have
implemented my own iterator.
public class ConcreteAggregate2: IAggregate {
// fields
protected int[] _dataCollection;
int _elementAdditionIndexor = -1;
// properties
/* NB. I have chosen to pass the collection class to the iterator,
rather than passing the private int array. This means that we
have to implement the following two properties. */
public int Length {
get { return _dataCollection.Length; }
}
public int this [int index] // Indexer declaration
{
get {
// Check the index limits.
if (index < 0 || index >= _dataCollection.Length)
return 0;
else
return _dataCollection[index];
}
set {
if (!(index < 0 || index >= _dataCollection.Length))
_dataCollection[index] = value;
}
}
// constructor
public ConcreteAggregate2(int aLength) {
_dataCollection = new int[aLength];
}
// methods
public void Add(int aNewMember) {
_dataCollection[++_elementAdditionIndexor] = aNewMember;
}
public IEnumerator GetEnumerator() {
return new Enumerator(this);
}
}
As you can see the GetEnumerator methods now instantiates a object of
my new Enumerator class. I pass a reference to the aggregate instance
into the iterator.
// This is the Iterator for use with ConcreteAggregate2.
public class Enumerator: IEnumerator {
// fields
protected ConcreteAggregate2 _internalCollection;
int _arrayIndexor;
// constructors
internal Enumerator(ConcreteAggregate2 aCollection) {
_internalCollection = aCollection;
_arrayIndexor = _internalCollection.Length;
}
// properties
public object Current {
get {
if (_arrayIndexor == _internalCollection.Length)
throw new InvalidOperationException(
"You are at EOF");
if (_arrayIndexor == -1)
throw new InvalidOperationException(
"You need to issue MoveNext before the first record is available");
return _internalCollection[_arrayIndexor];
}
}
// methods
public bool MoveNext() {
if (_arrayIndexor < 0)
throw new InvalidOperationException(
"You are already at BOF");
return --_arrayIndexor > -1;
}
public void Reset() {
_arrayIndexor = _internalCollection.Length;
}
}
Simple code, but quite a lot of it ! Now we fully appreciate the
Iterator support that is inbuilt into the dotNet framework.
I would have made life for simple for myself if I had passed the
underlying array into the Iterator. This way I could have avoided
having to implement the Length and indexer properties for my
aggregate class.
Another simplification could have been if I had defined the
iterator as a "nested type" (see C# help text) within the
aggregate class. In this way the iterator could have had access to
the aggregate's private state. I chose not to implement it as a
nested type as I wanted to inherit from the Iterator in the following
illustration.
For a final look at the iterator pattern we shall look at an
Internal iterator, where the the client is passive, and the iterator
steps through the collection itself. In this illustration I pass an
invocation list of methods into the iterator via a delegate. The
internal iterator will step through the collection, and apply each
method within the invocation list against each element within the
collection.
Firstly let us look at the client's definition of the methods that
will be included in the invocation list.
/*----------------------------------------------------------------
These two methods are placed into a delegate's invocation list to be
called against each member within the aggregate's collection by the
internal iterator. */
public void ShowValue(int aMember) {
listBox1.AppendText(String.Format(
"n Element value is {0}",aMember.ToString()));
}
public void ShowWhetherOddOrEven(int aMember) {
string st = ((aMember%2)==0)?"Even":"Odd";
listBox1.AppendText(String.Format("n Element value is {0}",st));
}
The next snippet shows the client creating, and loading, the
aggregate. It then creates an delegate (the definition will come
later), and then loads it's invocation list with the above two
methods. Finally it obtains an internal iterator for the aggregate
and instructs the iterator to step through the dataset applying the
invocation stack to each member. The iterator used descends from the
one created in the previous example , so the elements will will be
presented in reverse sequence.
/* The above examples used an EXTERNAL iterator, now try an INTERNAL
iterator where the client is passive, and the Iterator does the
navigation through the collection. */
ShowUserCommentary(4);
ConcreteAggregate3 aggNew = new ConcreteAggregate3(2);
aggNew.Add(10);
aggNew.Add(11);
/* Create a delegate with an invocation list. The methods in the
list are to be applied to each member in the aggregate's collection. */
OperatorsForAggregate operations = null;
operations += new OperatorsForAggregate(ShowValue);
operations += new OperatorsForAggregate(ShowWhetherOddOrEven);
// Create the Internal Iterator
IInternalEnumerator iteratorInternal = aggNew.GetEnumerator();
/* Tell the internal iterator to navigate through the collection and
apply the invocation list to each member. */
iteratorInternal.Traverse(operations);
The output is as follows:

Now to the implementation. Firstly the definition for the delegate
type that will be used to hold the invocation list that is passed
from the client. A delegate is basically a function pointer which can
reference more than one method at a time. Each of the methods to be
referenced has to have the same method signature as the delegate's
definition. Our client has attached the ShowValue and
ShowWhetherOddOrEven methods to this delegate.
/* This delegate is used to pass an invocation list into the Internal
Iterator's Traverse method. */
public delegate void OperatorsForAggregate(int aMember);
Next we define the aggregate class. I will save myself a lot of work
if I inherit from the aggregate class that we defined for the prior
example, all i need to do is override the getEnumerator method to
return the new internal iterator.
public class ConcreteAggregate3: ConcreteAggregate2 {
// constructor
public ConcreteAggregate3(int aLength): base(aLength) {
_dataCollection = new int[aLength];
}
// methods
new public InternalEnumerator GetEnumerator() {
return new InternalEnumerator(this);
}
}
Finally the internal Iterator class. Again I will descend from the
iterator that we built for prior example, as I need the same Current,
MoveNext and Reset functionality. I will then extend it to provide
the Traverse method. This method will iterate through the collection,
and apply the invocation list against each element.
public interface IInternalEnumerator: IEnumerator {
// methods
void Traverse(OperatorsForAggregate aOperationList);
}
public class InternalEnumerator: Enumerator, IInternalEnumerator {
// constructors
internal InternalEnumerator(ConcreteAggregate2 aCollection):
base(aCollection) {
_internalCollection = aCollection;
}
// methods
public void Traverse(OperatorsForAggregate aOperationList) {
// apply the invocation list to each collection member
foreach (int i in _internalCollection) {
aOperationList(i);
}
}
}
Mediator Pattern
The Mediator pattern collects the rules of interaction between a
number of objects (Colleagues) and encapsulates these into a separate
Mediator object.
The adoption of OO leads to a situation where the behaviour of our
application becomes distributed across a number of classes and
objects. This can facilitate code reuse, and aid in the comprehension
of the application's functionality. However these deliverables break
down where our application design requires too many "many to
many" relationships. We can get into a tangled web where our
objects need to know about too many other objects. This will reduce
the opportunity of reuse, and will obscure the design of the system.
By outsourcing the rules of interaction into a third party we
promote a more loosely coupled design which can have the following
benefits:
facilitate more reuse. We could build a new type of Mediator
which will have our reused Colleagues working together in a new way,
or we could build new types of Colleague and our old Mediator would
still coordinate their interaction in the same expected manner. New
Colleague classes can be introduced with minimal disruption.
aid understanding. Since the cooperation between the
Colleagues is collected into the one place the big picture can
become easier to understand.
A Mediator pattern will often be used in a Windows Forms
application where there is a good deal of interaction between GUI
elements on the form. If you are familiar with Delphi you may
recognise that part of the role of the ActionManager and ActionList
components is to act as Mediators.
My demonstration program shows a set of Colleague classes which
can be coordinated by a Mediator. Both the Colleague and Mediator
types have a property named Enabled. The client can control the
Enabled status of an isolated Colleague object. It can also control,
as a group, any Colleague instances which have been enrolled with a
Mediator object. This is shown in the following client code.
Firstly we have a service method that display the status of a list
of Colleagues so that we can see what is going on.
private void ShowStatus(params ColleagueBase[] aColleagueList) {
foreach (ColleagueBase col in aColleagueList) {
listBox1.AppendText(String.Format(
"nInstance named {0} of type {1}; Enabled status = {2}",
col.Name,col.ToString(),col.Enabled.ToString()));
}
}
Then the client code to run the demonstration.
MediatorConcrete mediatorA = new MediatorConcrete();
/* Create three Colleagues; two different types, two connected to a
Mediator, and one not connected. */
ColleagueBase colleagueA = new ColleagueConcrete_A("ColleagueA", mediatorA);
ColleagueBase colleagueB = new ColleagueConcrete_B("ColleagueB", mediatorA);
ColleagueBase colleagueC = new ColleagueConcrete_A("ColleagueC");
// Show initial enablement status.
ShowUserCommentary(1);
ShowStatus(colleagueA, colleagueB, colleagueC);
// Enable the Mediator's. Will enable any connected colleagues.
mediatorA.Enabled = true;
ShowUserCommentary(2);
ShowStatus(colleagueA, colleagueB, colleagueC);
// Attach the third Colleague. It's status will now fall into line.
colleagueC.Mediator = mediatorA;
ShowUserCommentary(3);
ShowStatus(colleagueA, colleagueB, colleagueC);
/* Detach one of the Colleagues. It is now cut adrift from any
changes to the Mediator. */
colleagueB.Mediator = null;
mediatorA.Enabled = false;
ShowUserCommentary(4);
ShowStatus(colleagueA, colleagueB, colleagueC);
This results in the following output.

The basic public interface for the pattern could be described as:
public interface IColleague {
// properties
IMediator Mediator {get; set;}
}
public interface IMediator {
}
Now to the pattern implementation. I will examine two approaches, one
based upon the idea of having the Mediator keep a collection of
enrolled Colleagues, and the other implementation will use a callback
approach that employs dotNet's Event facility.
Here is the first approach where the Mediator keeps a reference
collection of enrolled colleagues.. Firstly let us look at the
Mediator. The key features from the pattern's perspective is the Add
and Remove methods, and foreach loop within the set accessor of any
property that the pattern is synchronizing.
// Mediator
public class MediatorConcrete {
// fields
private ArrayList _colleagues = new ArrayList();
protected bool _enabled = false;
// properties
public bool Enabled {
get { return this._enabled; }
set {
foreach (ColleagueBase colleague in _colleagues) {
colleague.Enabled = value;
}
this._enabled = value;
}
}
// methods
internal void Add(ColleagueBase aColleague) {
_colleagues.Add(aColleague);
}
internal void Remove(ColleagueBase aColleague) {
if (_colleagues.Contains(aColleague))
_colleagues.Remove(aColleague);
}
}
Then there is the base class for the Colleagues:
// Abstract Colleague
abstract public class ColleagueBase {
// fields
private MediatorConcrete _mediator;
protected bool _enabled = false;
protected string _name;
// properties
public MediatorConcrete Mediator {
set {
if (this._mediator != null)
this._mediator.Remove(this); // remove any prior Mediator
this._mediator = value;
if (value != null) {
this._mediator.Add(this);
// set our status as per the mediator that now controls us
this._enabled = value.Enabled;
}
}
get { return this._mediator; }
}
public bool Enabled {
set { this._enabled = value; }
get { return this._enabled; }
}
public string Name {
get { return this._name; }
}
// constructors
public ColleagueBase(string aName) {
this._name = aName;
}
public ColleagueBase(string aName, MediatorConcrete aMediator) {
_name = aName;
this.Mediator = aMediator;
}
}
Finally the Colleague concrete classes:
// Concrete Colleagues
public class ColleagueConcrete_A: ColleagueBase {
// constructors
public ColleagueConcrete_A(string aName): base(aName) {}
public ColleagueConcrete_A(string aName, MediatorConcrete aMediator)
: base(aName, aMediator) {}
}
public class ColleagueConcrete_B: ColleagueBase {
// constructors
public ColleagueConcrete_B(string aName): base(aName) {}
public ColleagueConcrete_B(string aName, MediatorConcrete aMediator)
: base(aName, aMediator) {}
}
Now to an alternate implementation of the Mediator pattern. Whenever
the Mediator's status is changed it uses dotNet's event facility to
call a callback method in the Colleague. Firstly we shall look at the
client. As you will see the client is unaware of the change in
implementation.
MediatorConcrete_V2 mediatorV2 = new MediatorConcrete_V2();
mediatorV2.Enabled = true;
ColleagueBase_V2 colleagueD = new ColleagueConcrete_V2_A("ColleagueD");
ColleagueBase_V2 colleagueE =
new ColleagueConcrete_V2_A("ColleagueE",mediatorV2);
ShowUserCommentary(5);
ShowStatus(colleagueD, colleagueE);
colleagueD.Mediator = mediatorV2;
ShowUserCommentary(6);
ShowStatus(colleagueD, colleagueE);
mediatorV2.Enabled = false;
ShowUserCommentary(7);
ShowStatus(colleagueD, colleagueE);
This will produce the following output:

Now to the implementation. I will inherit from the Mediator from
the previous version. Firstly we define an event called
EnableChanged. Our event will not generate any data, so we can just
use dotNet's inbuilt base event handling delegate called
Eventhandler. This has just a "this" reference and a null
set of arguments, which is all we need for this example.
We then define an event handling method (OnEnabledChanged) which
will call the event delegate's invocation list which contain any
callback routines that the Colleagues have registered against this
event. Then we reimplement the Enabled property to raise the event
whenever the Mediator's Enable status is changed.
// Mediator - V2
public class MediatorConcrete_V2: MediatorConcrete {
// properties
new public bool Enabled {
get { return this._enabled; }
set {
if (this._enabled != value) {
this._enabled = value;
if (EnableChanged != null) {
EventArgs e = new EventArgs();
OnEnabledChanged(e);
}
}
}
}
// events
public event EventHandler EnableChanged;
// methods
protected virtual void OnEnabledChanged(EventArgs e) {
if (EnableChanged != null) {
EnableChanged(this, e);
}
}
// the following two methods are not in use in this implementation
new internal void Add(ColleagueBase aColleague) {}
new internal void Remove(ColleagueBase aColleague) {}
}
Finally the Colleagues. We define a callback method (SetEnabled) that
is to be called by the controlling Mediator's EnabledChanged event.
Then we modify the Colleague's Mediator property so that whenever the
Colleague is attached to a Mediator, the Colleague's callback method
is wired to the Mediator's EnabledChanged event.
// Abstract Colleague
abstract public class ColleagueBase_V2: ColleagueBase {
// fields
private MediatorConcrete_V2 _mediator;
// properties
new public MediatorConcrete_V2 Mediator {
set {
if (this._mediator != null)
this._mediator.EnableChanged -=
new EventHandler(this.SetEnabled);
if (value != null) {
this._mediator = value;
this._mediator.EnableChanged +=
new EventHandler(this.SetEnabled);
this.Enabled = value.Enabled;
}
}
get { return this._mediator; }
}
// contructors
public ColleagueBase_V2(string aName): base(aName) {}
public ColleagueBase_V2(string aName, MediatorConcrete_V2 aMediator)
: base(aName) {
this.Mediator = aMediator;
}
// methods
/* This is a callback method for use by the Mediator whenever it
receives a change of status. */
private void SetEnabled(object sender, EventArgs e) {
this._enabled = ((MediatorConcrete_V2)sender).Enabled;
}
}
// Concrete Colleagues
public class ColleagueConcrete_V2_A: ColleagueBase_V2 {
// constructors
public ColleagueConcrete_V2_A(string aName): base(aName) {}
public ColleagueConcrete_V2_A(string aName,
MediatorConcrete_V2 aMediator): base(aName, aMediator) {}
}
Observer pattern
This pattern has some similarity to the Mediator
Pattern that we have just looked at. With the Mediator the
communication between objects was outsourced to a Mediator object,
while in the the Observer pattern communication is handled by the
objects themselves. The pattern has two classes of participant;
Subject and Observers.
The Subject:
is observed
knows which Observers are observing it
sends notification to interested observers whenever it's
state changes
has interfaces for attaching and detaching Observers
The Observer:
An Observer can observe more than one subject, and an Observer
could also act as a Subject itself, being observed by other
Observers.
Use of the pattern can have the following benefits:
allow the application to have cohesion between classes
without tight coupling
allow independent enhancement, or reuse, of Subjects or
Observers
implement flexibility as observers can be added or removed at
runtime, or subsequent versions of the application could introduce
new observer classes with minimal disruption.
There are several implementation options. Firstly:
PULL Mode; where the Subject says "My state has
changed", and the Observers have to determine for themselves
what changed.
PUSH Mode; where the Subject provides the Observers with an
information package showing what has changed.
Another implementation variation regards which entity is
responsible for issuing "Notify" to trigger the Observers
telling them that the Subject has changed:
CLIENT; here the client that is making the updates to the
Subject is responsible for calling "Notify" when it has
completed the logical update. This would reduce the traffic in the
case of an update that involved a series of small linked changes,
but it exposes the application to a bug if a client forgets to
trigger the "notify".
SUBJECT; here the Subject issues "Notify" whenever
it receives any single update to an observed member, regardless of
whether there are further updates still to come which form part of
the logical transaction. There will be increased traffic in the case
of such linked updates, but better protection against a missing
"notify".
My demonstration program illustrates these implementation options.
The first example requires the CLIENT to issue the Notify.
Internally, as we shall see later, the pattern is implemented in PULL
mode. The implementation also does an auto-notify when the Observer
is attached to the Subject.
// Create a Subject, then attach two Observers
Subject subject1 = new Subject("Expensive Item",100.0m,5);
ObserverBase observer1 = new ObserverConcrete_1("Observer1");
ObserverBase observer2 = new ObserverConcrete_2("Observer2");
subject1.Attach(observer1);
subject1.Attach(observer2);
// Show initial status of Subject and Observers
ShowUserCommentary(1);
ShowStatus(subject1, observer1, observer2);
/* Change the Subject's state, show all statuses again.
The Subject in use is expecting the client to issue "Notify"
when it is finished any linked updates, so the Observer's status
is unchanged at this time. */
subject1.Name = "Cheap";
subject1.Price -= 75m;
subject1.Available -= 3;
ShowUserCommentary(2);
ShowStatus(subject1, observer1, observer2);
/* We issue "Notify", then show that the Observer's have received
the changes. */
ShowUserCommentary(3);
subject1.Notify();
ShowStatus(subject1, observer1, observer2);
This produces the following output:

Our demonstration now continues, this time using a Subject that
has been implemented to auto-notify whenever one of the observed
members change. This results in better bug proofing, but higher
communications traffic. You cannot tell from the outside, but this
implementation is working in PULL mode also.
/* Create another form of Subject. This one will auto-notify
whenever it receives an update. Reduced possibility of a
missing "notification" bug, but increased traffic in the case
of an linked update involving separate steps. */
Subject2 subject2 = new Subject2("Expensive",100.0m,5);
observer1 = new ObserverConcrete_1("Observer1");
observer2 = new ObserverConcrete_2("Observer2");
subject2.Attach(observer1);
subject2.Attach(observer2);
subject2.Name = "Cheaper";
subject2.Price -= 85m;
subject2.Available -= 4;
ShowUserCommentary(4);
ShowStatus(subject2, observer1, observer2);
Giving this output:

The basic public interface for the package could be described as:
public interface IObserver {
// methods
virtual public void Update(ISubject aSubject);
}
public interface ISubject {
// methods
void Attach(IObserver aObserver);
void Detach(IObserver aObserver);
void Notify();
}
Now to the implementation. As with the Mediator Pattern I will show
two alternate implementations; the first works by having the Subject
keep a reference collection of it's Observers, and the second uses
dotNet's event facility and an Observer callback method.
For the first illustration we start with a base class for our
Observers. The part that is important from the pattern's perspective
is the "Update" method. This method is going to be called
by the Subject's "Notify" method.
The other members are just part of the demonstration. Both of the
concrete Observers will watch the Observer's "Name" and
"Price" properties. We have a UpdateCount property so
that we can track the implementation's communication cost, and "ID"
property so that the Observer's can identify themselves in the
runtime commentary.
// --- Abstract Observer
public abstract class ObserverBase {
// fields
private string _name, _id;
private decimal _price;
private int _updateCount = -1;
// properties
public string Name {
get { return _name; }
}
public string ID {
get { return _id; }
}
public decimal Price {
get { return _price; }
}
public int UpdateCount {
get { return _updateCount; }
}
// constructors
public ObserverBase(string aID) {
_id = aID;
}
// methods
virtual public void Update(Subject aSubject) {
if (this.Name != aSubject.Name)
_name = aSubject.Name;
if (this.Price != aSubject.Price)
_price = aSubject.Price;
_updateCount++;
}
}
The next code snippet contains the declaration for the concrete
Observer classes. The second of these builds upon the base class to
add observation of the Subject's "Available" property.
// --- Concrete Observers
public class ObserverConcrete_1: ObserverBase {
// constructors
public ObserverConcrete_1(string aID): base(aID) {}
}
public class ObserverConcrete_2: ObserverBase {
// fields
private int _available;
// properties
public int Available {
get { return _available; }
}
// constructors
public ObserverConcrete_2(string aID): base(aID) {}
// methods
override public void Update(Subject aSubject) {
base.Update(aSubject);
if (this.Available != aSubject.Available)
_available = aSubject.Available;
}
}
Now to the Subject. We will firstly look at the version that relied
upon the client issuing the call to "Notify". The
implementation is based upon the Subject maintaining a collection of
attached observers. The important parts from the pattern's
perspective are the Attach and Detach methods, and the Notify method
which calls the Observers' Update methods.
// --- Subject
public class Subject {
// fields
private ArrayList _observers = new ArrayList();
protected int _available;
protected string _name;
protected decimal _price;
// properties
virtual public int Available {
set { _available = value; }
get { return _available; }
}
public string Name {
get { return _name; }
set { _name = value; }
}
public decimal Price {
get { return _price; }
set { _price = value; }
}
// constructors
public Subject(string aName, decimal aPrice, int aAvailable) {
_name = aName;
_price = aPrice;
_available = aAvailable;
}
// methods
public void Attach(ObserverBase aObserver) {
_observers.Add(aObserver);
aObserver.Update(this);
}
public void Detach(ObserverBase aObserver) {
_observers.Remove(aObserver);
}
public void Notify() {
foreach (ObserverBase observer in _observers) {
observer.Update(this);
}
}
}
Then we have the second version of the subject which issued it's own
auto-notify whenever one of the observed members changed. This
version descends from the first, but overrides the observed
property's "set" accessor to add the call to "Notify".
public class Subject2: Subject {
// properties
override public int Available {
set {
base.Available = value;
this.Notify();
}
get { return base.Available; }
}
new public string Name {
set {
base.Name = value;
this.Notify();
}
get { return base.Name; }
}
new public decimal Price {
set {
base.Price = value;
this.Notify();
}
get { return base.Price; }
}
// constructors
public Subject2(string aName, decimal aPrice, int aAvailable):
base(aName, aPrice, aAvailable) { }
}
Now let us look at an alternative implementation using dotNet's event
facility. This will be similar to our second example of the Mediator
pattern, except this time we will generate an event that contains
data so that we can demonstrate an Observer Pattern using PUSH mode
communications. Firstly some client code to run the illustration:
EventSubject subject3 = new EventSubject();
EventObserver observer3 = new EventObserver("Observer3");
EventObserver observer4 = new EventObserver("Observer4");
subject3.Attach(observer3);
subject3.Attach(observer4);
subject3.Name = "Orange";
subject3.Price = 0.15m;
// Show initial status.
ShowUserCommentary(5);
ShowStatus2(subject3, observer3, observer4);
// Change the Subject. Both Observers are affected.
subject3.Name = "Big Orange";
ShowUserCommentary(6);
ShowStatus2(subject3, observer3, observer4);
/* Detach one Observer, then change the Subject again. Only the
attached Observer is affected. */
subject3.Detach(observer3);
subject3.Price = 0.35m;
ShowUserCommentary(7);
ShowStatus2(subject3, observer3, observer4);
This produces the following output:

The first step for our implementation is to define a class which
will contain the event data having the details of the change that has
occurred to the Subject. Part of this information package will be a
switch showing which of the subject's members was the target for the
change.
// --- Switch settings; show which field was affected by the update.
public enum TargetChange {Name, Price};
// --- Class to contain event data
public class SubjectChangedEventArgs : EventArgs {
// fields
private string _newName;
private decimal _newPrice;
private TargetChange _changeTarget;
// properties
public TargetChange Target {
get { return _changeTarget; }
}
public string NewName {
get { return _newName; }
}
public decimal NewPrice {
get { return _newPrice; }
}
// constructors
public SubjectChangedEventArgs (string aNewName) {
_newName = aNewName;
_changeTarget = TargetChange.Name;
}
public SubjectChangedEventArgs (decimal aNewPrice) {
_newPrice = aNewPrice;
_changeTarget = TargetChange.Price;
}
}
Then the Observer. The important part is the event handler called
Subject Changed. This is the callback method that will handle the
SubjectChanged event. The event handler receives the PUSH MODE
information package and reacts to reflect the subject change within
the Observer.
// --- the Observer
public class EventObserver {
// fields
private string _name, _ID;
private decimal _price;
//properties
public string ID {
get { return _ID; }
}
public string Name {
get { return _name; }
}
public decimal Price {
get { return _price; }
}
//constructors
public EventObserver(string aID) {
_ID = aID;
}
//methods
internal void SubjectChanged(object sender, SubjectChangedEventArgs e) {
switch (e.Target) {
case TargetChange.Name:
this._name = e.NewName;
break;
case TargetChange.Price:
this._price = e.NewPrice;
break;
default:
throw new ApplicationException("Unexpected change target");
}
}
}
Then we define a delegate that will point to our event handler. The
argument class defined above is passed as a parameter.
// --- Event's delegate
public delegate void SubjectChangedEventHandler
(object sender, SubjectChangedEventArgs e);
The final step is the definition of the Subject:
defines an SubjectChanged event whose type is the event
delegate described above.
defines Attach & Detach methods to wire or unwire the
event to a Observer's event handler
defines an method called OnSubjectChanged to raise the event.
The list of connected Observers is obtained from the delegate's
invocation list.
The observered member's set assessors raise the event
whenever a change is made to the subject.
// --- the SUBJECT
public class EventSubject {
// fields
private string _name;
private decimal _price;
// properties
public string Name {
set {
_name = value;
OnSubjectChanged(new SubjectChangedEventArgs(value));
}
get { return _name; }
}
public decimal Price {
set {
_price = value;
OnSubjectChanged(new SubjectChangedEventArgs(value));
}
get { return _price; }
}
// events
public event SubjectChangedEventHandler SubjectChanged;
// methods
public void Attach(EventObserver aObserver) {
this.SubjectChanged +=
new SubjectChangedEventHandler(aObserver.SubjectChanged);
}
public void Detach(EventObserver aObserver) {
this.SubjectChanged -=
new SubjectChangedEventHandler(aObserver.SubjectChanged);
}
protected virtual void OnSubjectChanged(SubjectChangedEventArgs e) {
if (SubjectChanged != null)
SubjectChanged(this, e);
}
}
Momento Pattern
This pattern allows us to save, or restore, an object's internal
state without violating it's encapsulation.
There are three participants within the Momento pattern:
The Originator:
can save it's own state to a new Momento object, which it
creates for this purpose
can use a Momento object to restore it's state back to a
checkpoint
The Momento:
The Caretaker:
triggers the Originator to create checkpoint Momento objects
keeps a reference to Momentos that are created
can pass a Momento back into the Originator, and then trigger
the Originator to perform an "undo" operation to return
it's state back to a prior checkpoint
cannot see any of the Originator's non-public information,
that is stored inside the Momentos
A benefit of the Momento Pattern is that the Originator can
provide undo capabilities without the overhead of having to cache
multiple checkpoints within itself.
The GOF advise that the pattern should be implemented such that
the Momento offers the Originator a "wide" interface so
that it can store or retrieve all of it's internal secrets. However
the Momento should only offer the rest of a world a "narrow"
interface so that the Originator's internal secrets are protected.
They also say that it would also be preferable if the pattern could
be implemented such that a Momento instance could only be used by the
Originator instance which created it, if the application requires
this restriction.
The challenge is how to implement this prescription. C# doesn't
have the "friend class" capability of C++, so we have
restrictions as to how we can offer the Originator private
access into the Momento's private members. Just how seriously we have
to take this challenge depends upon our motivations for requiring
privacy. Maybe we are the designer of the Originator class, and just
want to protect against some downstream programmer from relying upon
internal Originator details that may need to be changed some time in
the future. The answer to this challenge is easier to satisfy than a
situation where the Originator contains sensitive data, and we are
concerned about unauthorised viewing of information stored in
persisted Momentos.
We could perhaps partially attend to the "narrow interface"
requirement by using the internal access modifying attribute
on sensitive Momento properties, but that would only work if the
Momento and the Originator were compiled in the same assembly, and
the Caretaker and the rest of the outside world were not in that
assembly.
Another possible technique would be to define the Originator class
as a nested type within the Momento class. This would allow the
Originator to access the Momento's private variables.
Both these approaches seem clumsy to me, and without further work
they have a problem. If the Momento is to be persisted to disk, the
disk copies of the Momentos could disclose the Originator's state
information. This could be a problem if this information needed to be
kept confidential.
A third approach could be to encrypt the Momento with a secret key
known only to the Momento and it's Originator instance. This
technique enables us to solve a few issues:
Momentos persisted to disk will not readily disclose
sensitive information
solves the "narrow" access issue as no object will
be able to make sense of a Momento without the encryption keys
will help us to implement the optional requirement that only
the originating Originator will be able to accept back a Momento.
I illustrate each of these approaches in my demonstration program.
The first illustration has the following client (Caretaker) code:
// Create an Originator, set and display it's initial state
Originator originator = new Originator();
originator.State = "original";
ShowUserCommentary(1);
listBox1.AppendText(String.Format("nstate = {0}", originator.State));
/* Instruct the Originator to create a Momento, then change the
state of the Originator. */
IMomento momento = originator.CreateMomento();
originator.State = "changed";
ShowUserCommentary(2);
listBox1.AppendText(String.Format("nstate = {0}", originator.State));
/* Instruct the Originator to restore it's state to as it was when
the Momento was created. */
originator.SetMomento(momento);
ShowUserCommentary(3);
listBox1.AppendText(String.Format("nstate = {0}", originator.State));
This produces the following output:

The essential interface to be implemented is as follows:
// --- interfaces
public interface IMomento {
// properties
// <=== will be marked internal to protect Originator's state
}
public interface IOriginator {
// methods
IMomento CreateMomento(); // create a checkpoint
void SetMomento(IMomento aMomento); // "undo" back to a checkpoint
}
For our first implementation approach we will use the internal
access modifier to protect the Originator's private information from
public view. This approach relies upon us having an assembly for the
Originator and Momento classes that is separate from the assembly
that contains classes not authorised to access the Momento's
properties. My demonstration program has this assembly division as
the patterns are implemented in the Patterns dll, and the Caretaker
code is in the exe file. The "internal" access modifier
on the properties will only allow access to types defined within the
same assembly as the Momento class. The "internal"
modifier on the constructor will protect our application's integrity
as fake Momentos cannot be created outside the trusted environment.
Here is the implementation for the Momento type:
// --- Momento
public class Momento: IMomento {
// fields
private string _state;
// properties
internal string State {
get { return _state; }
}
// constructor
internal Momento(string aState) {
_state = aState;
}
}
Then the Originator Type. In this example I have only one item of
"state" to save into the Momento. A real example would
obviously handle multiple items of state. The only piece of
Originator "state" that I have handled is a public
property that is visible to the client. This is so that I can display
the result following recreation of state in my demonstration program.
A real example could include private Originator information as well
as it's public members.
// --- Originator
public class Originator: IOriginator {
// fields
private string _state;
// properties
public string State {
get { return _state; }
set { _state = value; }
}
// methods
/* ----------------------------------------
Create a Momento.
------------------------------------------- */
public IMomento CreateMomento() {
return new Momento(_state);
}
/* --------------------------------------------
Recreate state from a Momento.
----------------------------------------------- */
public void SetMomento(IMomento aMomento) {
this.State = ((Momento)aMomento).State;
}
}
The next implementation alternative that we shall look at will define
the Momento's constructor and properties with the "private"
access modifier. This is an improvement over the first approach that
we looked, at as there is no longer a need to have a separate
assembly for our "trusted" environment. The downside of
this approach is that Originator has to be defined as a nested type
within the Momento type. This is clumsy, but is the only way that we
can arrange things so that the Originator has access to the Momento's
private members.
Here is some client code to test this second implementation:
/* Try a different implementation giving another way of protecting
the privacy of information held within the Momento. */
Momento_2.NestedOriginator nestOriginator = new Momento_2.NestedOriginator();
nestOriginator.State = "other";
Momento_2 nestedMomento = nestOriginator.CreateMomento();
nestOriginator.State = "other_changed";
nestOriginator.SetMomento(nestedMomento);
Now to the implementation. As you can see the Originator type is
defined within the Momento type, this is called a"nested type"
and gives the inner type access to the outer type's private members.
The "private" access modifier on the Momento's
constructor and State property will mean that classes other than the
Originator cannot construct Momentos, nor can they access it's
properties. The Originator has a public constructor which allows the
client (Caretaker) to construct it, and it has a public CreateMomento
methods which allows the Originator to create Momentos and pass them
to the Caretaker for safe keeping.
/* ----------------------------------------------------------------------
Alternate implementation. The Originator is defined as a nested
class within the Momento. The aim is to allow the Originator to
have access to the Momento's private state, without exposing
this to other classes.
------------------------------------------------------------------------ */
public class Momento_2 {
// fields
private string _state;
// properties
private string State {
get { return _state;}
}
// constructor
private Momento_2(string aState) {
_state = aState;
}
public class NestedOriginator {
// fields
private string _state;
// properties
public string State {
get { return _state;}
set { _state = value;}
}
// methods
public void SetMomento(Momento_2 aMomento) {
this.State = aMomento.State;
}
public Momento_2 CreateMomento() {
return new Momento_2(_state);
}
}
}
The worst of this implementation is the client's declaration of the
Originator:
Momento_2.NestedOriginator nestOriginator = new Momento_2.NestedOriginator();
This can be improved if we provide the client with a "using"
directive to create an alias for the nested class.
using System;
using System.Windows.Forms;
using Momento;
// define an alias to represent a namespace
using Originator_2 = Momento.Momento_2.NestedOriginator;
This means that we can now recode the Originator's declaration as
Originator_2 nestOriginator = new Originator_2(); // uses alias
Now let us return to the first implementation approach, and extend it
to have the CreateMomento method persist the Momento to disk, and
pass back just the file name rather than the Momento itself. Apart
from the obvious feature that our Momentos can now remain available
for use beyond the current execution instance of our application, it
can also ease one of the privacy exposure issues that exist with the
"internal" access modifier's on the Momento's members.
The privacy concern may just arise from a desire on the part of the
Originator's Programmer to ensure that a downstream Programmer,
creating the Caretaker client within the same assembly, does not gain
access to the Momento's properties. The concern would be that the
downstream programmer comes to rely upon internal implementation
details that we may need to change in the future.
In this new implementation of the Momento pattern the Originator
persists the Momento to disk, and just passes back a file name, the
Momento as an object is unavailable to the outside world, as it only
exists as an instantiated object within the Originator.
Here is some client code to test this new implementation:
/* Instruct the Originator to create, and persist to disk, a
Momento. Change the originator's state again. */
originator.CreateMomento("momento_1.txt");
originator.State = "changed again";
ShowUserCommentary(4);
listBox1.AppendText(String.Format("nstate = {0}", originator.State));
/* Instruct the Originator to restore state back to as it was when
the Momento was created. */
string aErrorMessage;
ShowUserCommentary(5);
if (originator.SetMomento("momento_1.txt", out aErrorMessage))
listBox1.AppendText(String.Format("nstate = {0}", originator.State));
else
listBox1.AppendText(String.Format("nMomento cannot be restored; {0}",aErrorMessage));
The definition of the Momento class is as before, excepting that this
time it is marked with the Serializable attribute. This will cause
the type's meta data to be marked as needing serialization support
from the Common Language Runtime (CLR) when an object of this type is
instantiated. Serialization is the act of flattening out an in memory
object into a form that can be transmitted or stored.
// --- Momento
[Serializable]
public class Momento: IMomento {
// fields
private string _state;
// properties
internal string State {
get { return _state; }
}
// constructor
internal Momento(string aState) {
_state = aState;
}
}
Then we create an overloaded version of the Originator's
CreateMomento method. An overloaded method shares the name of an
existing method, but has a different signature. The initial
implementation of the CreateMomento method had the following
signature which took no parameters, and returned an object that
satisfied the IMomento interface:
The overload version has an input parameter containing the name of
the new file that we are to create containing the serialized Momento.
The method returns a boolean indicating success or failure.
The overloaded method is as follows. The Momento is created,
serialized, written disk, and then the Momento object is discarded.
/* ----------------------------------------------
Create, and persist, a Momento.
---------------------------------------------- */
public bool CreateMomento(string aFileName) {
Stream fs;
if (File.Exists(aFileName)) {
fs = new FileStream(aFileName, FileMode.Open,
FileAccess.Write);
} else {
fs = new FileStream(aFileName, FileMode.CreateNew);
}
try {
IMomento momento = new Momento(_state);
IFormatter f = new BinaryFormatter();
f.Serialize(fs, momento);
} catch (Exception e) {
throw ApplicationException(
"Failed to create Momento, reason: "
+ e.Message);
} finally {
fs.Close();
}
return true;
}
The SetMomento method is overloaded as follows:
/* ----------------------------------------------
Recreate state from a Momento stored on disk.
------------------------------------------------- */
public bool SetMomento(string aFileName, out string aMessage) {
aMessage = "";
try {
using (FileStream fs = File.OpenRead(aFileName)) {
IFormatter f = new BinaryFormatter();
IMomento momento = (Momento)f.Deserialize(fs);
this.State = ((Momento)momento).State;
}
} catch (FileNotFoundException ex) {
aMessage = String.Format(
"File named "{0}" not found", aFileName);
return false;
}
return true;
}
This approach may have achieved the object of protecting the
encapsulation of Originator's internal state, but doesn't protect the
privacy of the information stored within the disk copies of the
Momentos. Here is the client's output from the above demonstration:

And here is the file created viewed with Notepad.

You will notice the Originator's state value (blue). This ready
availability may create a new privacy issue of it's own. If the
privacy of this information is an issue we could encrypt the Momento
before writing it to disk. This approach will improve the integrity
of our application as fake or corrupted Momentos would not be able to
be used to restore state to our Originators as the corruption would
cause the decryption step to fail. This approach will also help us to
address the pattern prescription that we haven't addressed yet, which
is to have the option to ensure that a Momento object can only be
used by the Originator instance that created it.
It may seem a bit over the top to use encryption if we are just
using it to ensure that our Momentos hasn't been corrupted or
altered, but this is a legitimate use of cryptography.
Cryptographical services are already built into the dotNet framework,
and are simple to use. One of the options is secret-key encryption
(aka symmetric encryption), which according to Microsoft's help text
is "extremely fast (compared to public-key algorithms) and are
well suited for performing cryptographic transformations on large
streams of data".
There are several flavours of symmetric algorithm available; DES,
RC2, Rijndael & TripleDES. I don't know anything about their
relative merits, so I have just used DES based upon nothing other
than it was the 1st in the list. Each method requires that
the encryptor, and the decryptor share a secret key. There is also an
Initialization Vector (IV) that doesn't need to be kept secret, but
is needed to decrypt the message. I have used the IV to enable me to
ensure that any specific Momento object can only be used by the
Originator instance that actually generated it.
Here is the same Momento, but encrypted before writing to disk.

Firstly some client code to demonstrate this new approach.
/* This time use an encrypted Momento to further protect the
privacy of the Originator's state.
Set the Originator's state, create a Momento, change
Originator's state again, then finally trigger the Originator
to restore state. */
originator.CreateSecureMomento("secure_momento.txt");
originator.State = "secure changed";
ShowUserCommentary(6);
listBox1.AppendText(String.Format("nstate = {0}", originator.State));
ShowUserCommentary(7);
if (originator.SetSecureMomento("secure_momento.txt", out aErrorMessage))
listBox1.AppendText(String.Format(
"nstate = {0}", originator.State));
else
listBox1.AppendText(String.Format("nMomento cannot be restored; {0}",aErrorMessage));
/* Create a different Originator object of the same type as the
first. Try and get it to use a Momento created by the first
Originator object. */
Originator originator_2 = new Originator();
originator_2.State = "someone_else";
originator_2.CreateSecureMomento("secure_momento_2.txt");
ShowUserCommentary(8);
if (originator_2.SetSecureMomento("secure_momento.txt", out aErrorMessage))
listBox1.AppendText(String.Format(
"nstate = {0}", originator_2.State));
else
listBox1.AppendText(String.Format("nMomento cannot be restored; {0}",aErrorMessage));
Giving this output:

To implement this we first add a new private field member to our
Originator class defined as "private byte[] _IV;" Then we
add a new method to the Originator class to create our encrypted
Momentos. We need to override the random encryption key that will be
generated by the encryption engine with our own eight character
string. In a real situation we would need to obfuscate this key
somehow rather than having it defined in a string as per my example.
During an Originator instance's first call to create a secure Momento
we will accept the random IV value that is auto-generated, as this
will uniquely identify this particular Originator object. We will
save the IV into a private member field, and also insert it into the
disk file which will also contain the Momento encrypted using that
IV. The same Originator object will use the saved IV for any
subsequent calls to create or use Momentos. In this way our
Originator will be able to refuse any incoming Momento that contain a
non-matching IV value. Alternatively we could allow our Originator to
accept anybody's Momento by just removing the equivalence check. The
other Originator would be able to decrypt the Momento because it also
knows the secret key, and the original Originator's IV value is
stored in the data stream.
One other thing is watch for is what the file system does when
recycling files. In the version of this method that produced
non-secure Momentos we just recycled the file if a file of our name
already existed. If the new Momento is smaller than the Momento that
last used the file, the last unused part of the file will contain
rubbish, as it is not truncated to the shorter length now required.
This didn't seem to worry the deserialization process, which must
mean that the serialization stream contains a header with a byte
count. This same technique doesn't work with decryption. Rubbish at
the end of the stream will cause a failure to decrypt (as I found out
after several hours of debugging <g>). So if a file of the same
name already exits, I delete it and create a fresh copy.
/* ----------------------------------------------
Create, and persist, an ENCRYPTED Momento.
------------------------------------------------- */
public bool CreateSecureMomento(string aFileName) {
bool retval = false;
FileStream fs;
if (File.Exists(aFileName))
/* If file exists, delete it. Don't recycle file because if
the new data is shorter than the previous contents, the length
won't be truncated. The bit of rubbish at the end will cause
the decrypt to fail at SetMomento method. */
File.Delete(aFileName);
using (fs = new FileStream(aFileName, FileMode.CreateNew)) {
try {
using (DESCryptoServiceProvider DES =
new DESCryptoServiceProvider()) {
/* Define a secret encryption key to be used for
Momentos that will be created with this Originator
class. We will use a fresh random Initialization
Vector with each momento instance */
ASCIIEncoding AE = new ASCIIEncoding();
DES.Key = AE.GetBytes("1z345678");
if (_IV == null)
_IV = (byte[])DES.IV.Clone();
else
DES.IV = _IV;
CryptoStream crypto = new CryptoStream(
fs, DES.CreateEncryptor(),
CryptoStreamMode.Write);
/* write the encryption's initialization vector out
to the file for use during decryption. */
fs.Write(DES.IV,0,DES.IV.Length);
using (MemoryStream ms = new MemoryStream()) {
/* Create the Momento, then serialize it out to
the MemoryStream ready to be encrypted. */
IMomento momento = new Momento(_state);
IFormatter f = new BinaryFormatter();
f.Serialize(ms, momento);
// Encrypt memorystream to disk.
byte[] b = ms.GetBuffer(); // b gets padded to 256
crypto.Write(b,0,b.Length);
crypto.FlushFinalBlock();
retval = true;
}
}
} catch (Exception e) {
throw new ApplicationException("Failed to serialize: "
+ e.Message);
}
}
return retval;
}
And finally the method to accept the Momento and recreate the
Originator's state back to when the Momento was created. The
behaviour can be changed to allow an Originator to accept any other
Originator's Momento by deleting the indicated logic block.
/* ----------------------------------------------
Recreate state from an ENCRYPTED Momento stored on disk.
------------------------------------------------- */
public bool SetSecureMomento(string aFileName, out string aMessage) {
aMessage = "";
try {
using (FileStream fs = File.OpenRead(aFileName)) {
using (DESCryptoServiceProvider DES =
new DESCryptoServiceProvider()) {
ASCIIEncoding AE = new ASCIIEncoding();
DES.Key = AE.GetBytes("1z345678");
/* Obtain, from disk, the initialization vector needed
to decrypt this momento */
byte[] IV = new byte[DES.IV.Length];
int ccc = fs.Read(IV,0,DES.IV.Length);
DES.IV = IV;
/* Refuse to apply the Momento if it was not created by
this Originator instance.
Delete this block if you want the Originator to
be to apply Momentos that were created by other
Originator instances. */
for (int i=0; i < this._IV.Length; i++) {
if (DES.IV[i] != this._IV[i]) {
aMessage = "Cannot restore somebody else's Momento";
return false;
}
}
CryptoStream crypto = new CryptoStream(
fs, DES.CreateDecryptor(),
CryptoStreamMode.Read);
// decrypt the serialized momento stream
byte[] b = new byte[(int)fs.Length-DES.IV.Length];
crypto.Read(b,0,(int)b.Length);
// load it into a memory stream
using (MemoryStream ms = new MemoryStream(b)) {
IFormatter f = new BinaryFormatter();
// Deserialize to reconstruct the Momento
IMomento momento = (Momento)f.Deserialize(ms);
this.State = ((Momento)momento).State;
}
}
}
} catch (FileNotFoundException ex) {
aMessage = String.Format(
"File named "{0}" not found", aFileName);
return false;
}
return true;
}
One final note before we leave the Momento pattern. I mentioned above
that we need to hide the secret key. I have included the following
image just in case you are unaware at how much information is
publicly available inside a dotNet executable. The dotNet compilers,
such as C#, compile to a Common Intermediate Language (CIL) which
contains a lots of meta data information about our types and methods.
We gain a lot of benefit from this approach such as interoperability
of languages, JIT compiling optimized for the environment we are
executing within, a very rich debugging environment, garbage
collection, serialization and deserialization support for our types
just to name a few examples.
However we do need to be aware that what is facilitating these
capabilities is very rich meta data embedded in our executables. The
following is a peek inside my Pattern's dll using an excellent free
class browser from Lutz Roeder (see link at bottom
of article). This information is available by looking into just
the dll, it doesn't need access to our source files. The need to
devise some method of hiding the secret key can be seen by looking at
where the cursor arrow is pointing half way up the right hand column.

Conclusion
This article has continued an examination of the GOF's Behavioural
Patterns from 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.
Look out for my closing article in this series where we will study
the remaining Behavioural Patterns.
Links
Connect with Us