Runtime flexibility and future proofing; GOF BEHAVIOURAL Patterns with C# - Part Two - by Barry Mossman

By: Barry Mossman

Abstract: This is the fourth article in a series upon the GOF Design patterns from a C# and .Net Framework perspective. It is a continuation of the BEHAVIORAL Patterns this time looking at Iterator, Mediator, Observer and Memento (Momento) patterns.

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:

    • Chain of Responsibility, Command, Interpreter

  • patterns deferred until my final article in this series:

    • State, Strategy, Template Method, Visitor

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):

    • External: where the client is responsible for moving the Iterator's cursor through the aggregate's members.

    • Internal: where the client is passive as regards navigation. The client asks the Iterator to traverse through the members, optionally passing in a operation for the Iterator to perform upon each

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:

  • reacts to change notifications received from the Subject

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:

  • contains the Originator's internal state as at the checkpoint

  • should not allow the outside world to see any of the Originator's non-public information

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:

  • public IMomento CreateMomento()

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.

  • bool CreateMomento(string aFileName)

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


Server Response from: SC4