C# Design Pattern : Observer



The observer pattern is basically a process where the change in an object's state (e.g. assignment of a property), must notify a list of dependant objects on that change.



The video clip above (if you're able to view it - thank you sony, you guys are awesome) is a scene from Lord of the rings where the beacons of Gondor gets lit in order to call for aid between Gondor and Rohan.

Which is a physical example of what we're trying to accomplish with this pattern - there is a call to lit the beacons, the guards (beacon bitches) observes that the neigbouring beacon is lit (change of state) and in turn they lit their own beacon causing a chain reaction of beacons getting lit.

Lets have a look at how to implement this pattern using C#.

Observe the following snippet:
 
interface IObserver
{
    void Update(Object subject);
}
 
abstract class Observable
{
    protected List<IObserver> container = new List<IObserver>();
 
    public void Attach(IObserver observer)
    {
        container.Add(observer);
    }
 
    public void Detach(IObserver observer)
    {
        container.Remove(observer);
    }
 
    protected void Notify()
    {
        foreach (IObserver observer in container)
        {
            observer.Update(this);
        }
    }
}
 

First of all what we've got here is an interface named IObserver - all classes that need notification of change in state (the observing classes), needs to implement this interface.

Secondly you will notice the abstract class Observable, which is the subject we wish to observe for change in state.

In the following snippet we implement & inherit the preceding snippets:
 
class Beacon : Observable
{
    private bool _IsLit;
    public bool IsLit
    {
        get
        {
            return _IsLit;
        }
        set
        {
            _IsLit = value;
            this.Notify();
        }
    }
}
 
class Observer : IObserver
{
    private string _name;
 
    public Observer(string name)
    {
        _name = name;
    }
 
    public void Update(Object subject)
    {
        Beacon beacon = (Beacon)subject;
        Console.WriteLine("Beacon at {0} {1}", _name, (beacon.IsLit) ? "lit" : "not lit");
    }
}
 

We create a class called "Beacon", which is the subject we wish to observe and add a property named "isLit" which triggers the notification.

Next we implement the interface IObserver on the "Observer" class - which represents the guys observing the beacons (the beacon bitches).

Finally we attach our observers to our beacon instance:
 
static void Main(string[] args)
{
    Beacon beacon = new Beacon();
    beacon.Attach(new Observer("Amon Dîn"));
    beacon.Attach(new Observer("Eilenach"));
    beacon.Attach(new Observer("Nardol"));
    beacon.Attach(new Observer("Erelas"));
    beacon.Attach(new Observer("Min-Rimmon"));
    beacon.Attach(new Observer("Calenhad"));
    beacon.Attach(new Observer("Halifirien"));
    beacon.IsLit = true;
}
 

All of this might seem awfully familiar if you've ever worked with events/delegates (I'd be surprised if you haven't) - since events are an implementation of the observer pattern in .NET.

In the following snippet we use an event "onLit" in order to achieve the same functionality:
 
class Beacon : List<string>
{
    public event Action<Beacon> onLit;
 
    private bool _IsLit;
    public bool IsLit
    {
        get
        {
            return _IsLit;
        }
        set
        {
            _IsLit = value;
            if (onLit != null)
            {
                onLit(this);
            }
        }
    }
}
 
class Program
{
    static void Main(string[] args)
    {
        Beacon beacon = new Beacon();
        beacon.onLit += new Action<Beacon>(beacon_onLit);
        beacon.Add("Amon Dîn");
        beacon.Add("Eilenach");
        beacon.Add("Nardol");
        beacon.Add("Erelas");
        beacon.Add("Min-Rimmon");
        beacon.Add("Calenhad");
        beacon.Add("Halifirien");
        beacon.IsLit = true;
    }
 
    static void beacon_onLit(Beacon obj)
    {
        foreach (string name in obj)
        {
            Console.WriteLine("Beacon at {0} {1}", name, (obj.IsLit) ? "lit" : "not lit");
        }
    }
}
 


Additional Reading:

http://stackoverflow.com/questions/32034/in-c-isnt-the-observer-pattern-already-implemented-using-events

Warning beacons of Gondor
http://tolkiengateway.net/wiki/Warning_beacons_of_Gondor

Microsoft article regarding the observer pattern
http://msdn.microsoft.com/en-us/library/ee817669.aspx

Gang of four article
http://www.dofactory.com/Patterns/PatternObserver.aspx




Post/View comments
 

Miscellaneous : Coalesce



The basic purpose of a coalesce function/operator is to return the first non null value in a list of values.

In SQL 2005/2008 a coalesce looks something like this:
 
DECLARE @a INT,
		@b INT,
		@c INT
 
SET @a = NULL
SET @b = 2
SET @c = NULL
 
SELECT COALESCE(@a, @b, @c)
 

Read more

In C# 2.0 Microsoft added nullable types to its codebase, which included what they call the null-coalescing operator, observe:
 
int? a = null;
int? b = 2;
int? c = null;
 
Console.WriteLine(a ?? b ?? c);
 

Basically if you need to make a value type nullable, simply add a question mark next to the type e.g. int?

The double question mark you see in the Console.WriteLine is the null-coalescing operator.

Read more
Read even more


In PHP 5.3, developer(s) added a coalescing operator:
 
$a = null;
$b = 2;
$c = null;
 
echo $a ?: $b ?: $c;
 

If you're not going to use any of the other new functionality added to PHP 5.3, there is no point in using this operator - since it will be treated as a syntax error in versions lower than 5.3 (breaking changes).

It might be prudent to treat 5.3 as a major version, but then again 5.3.3 introduced some breaking changes as well.

Read more
Read a bit more
Read some more





Post/View comments
 
First 11 12 13 14 15 16 17 18 19 20 Last / 62 Pages (124 Entries)

Latest Posts

Be the best stalker you can be


2011-12-13 22:33:54

Syntactic sugar (C#): Enum


2011-08-04 16:50:18

Top 5 posts

Simple WYSIWYG Editor


Creating a WYSIWYG textbox for your website is actually quite simple.
2007-02-01 12:00:00

Moving items between listboxes in ASP.net/PHP example


Move items between two listboxes in ASP.net(C#, VB.NET) and PHP
2008-06-12 17:07:43

Cross Browser Issues: Firefox Word Wrapping


Firefox word wrapping issues
2008-06-09 09:51:21

Populate a TreeView Control C#


Populate a TreeView control in a windows application.
2009-08-27 16:01:03

C# YouTube : Google API


Post on how to integrate with YouTube using the Google Data API
2011-03-12 08:37:51