Observer Pattern in F# : Simplified/Enhanced

One of the commonly used design pattern is the Observer Pattern because its just so easy to use and implement.  The classic OO way of implementing it is to have a Subject class having the methods "Attach", "Detach"  and "Notify". The Subject class usually stores the observers in an ArrayList and then when it needs to update the observers then iterates on the list and invokes the "Update" method of each observer. See diagram below.

Classic Observer Pattern

 

In C#, a more elegant way of implementing this is with Events and Delegates.  Here's a nice sample implementation.  By using using events and delegates, the code became a lot shorter and straight-forward 

In F#, implementation of the observer pattern became even more concise and elegant.  How come? Take a look at the code below.

line 11 : A clean and simple (one-liner!) way of creating events and triggers.  A call to IEvent.create is all it takes

lines 16 & 17 : calling "trigger" and passing the correct parameters notifies all listeners of the changeEvent.  We don't even need to check if there are listeners attached. If this is in C# we need to make changeEvent  != null otherwise a NullReferenceException will be raised.

lines 28 & 30.  In F# Events are first-class values , that means we can pass it around and more importantly we can do all sorts of wonderful things with it using the IEvent module.  For example,  in line 28, we filtered the event, basically saying that we are only interested in events of the Remove operation.  Now imagine if the Operation type (an enum actually, lines 5-7 ) contains more items such as Update, Delete, AddedThenRemoved, AddedThenUpdated, RemovedAddedAgainThenFinallyUpdated ... (you get what I mean).  If we want to a handle only the Remove operation then we'd have no choice but to break it down using an if-elseif-else or switch-case construct.  It would work but its not going to be pretty.  And this is where IEvent.filter shines. With just a single line of code (line 28, please ignore the comment above it.), we were able to filter out the event that we are only interested in. Apart from filtering, IEvent also allows us to map, partition, fold, split etc. events.

lines 25 & 30 : 2 ways of attaching to an Event.  I'm not very sure what's the difference between these 2. (TODO : Investigate)

F# Observer Pattern Code

Here's the output! Notice that the "observerForRemove" printed out only the message related to the Remove operation even though the Subject class raised 2 events (one for Add, another one for Remove) in the Notify() method at line 15.  Sweet.

output

 

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
Print | posted on Thursday, May 22, 2008 3:36 PM

Feedback

# re: Observer Pattern in F# : Simplified/Enhanced

left by Vlad at 4/25/2009 1:09 AM Gravatar
Hi Erik,

Nice article! By the way your code coloring looks very nice. Do you use some refactoring tool for F#?

# re: Observer Pattern in F# : Simplified/Enhanced

left by Erik at 4/29/2009 10:51 AM Gravatar
Hi Vlad,

No I don't use any refactoring tool. Do you know of any? I haven't done much F# coding these days...

# re: Observer Pattern in F# : Simplified/Enhanced

left by Vlad at 6/23/2009 3:54 AM Gravatar
I don't know, I hope Resharper or CodeRush will jump on that soon
Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: