Geeks With Blogs
Buhay Programmer Dont byte more than you can chew

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

 

Posted on Thursday, May 22, 2008 3:36 PM | Back to top


Comments on this post: Observer Pattern in F# : Simplified/Enhanced

# re: Observer Pattern in F# : Simplified/Enhanced
Requesting Gravatar...
Hi Erik,

Nice article! By the way your code coloring looks very nice. Do you use some refactoring tool for F#?
Left by Vlad on Apr 25, 2009 1:09 AM

# re: Observer Pattern in F# : Simplified/Enhanced
Requesting 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...
Left by Erik on Apr 29, 2009 10:51 AM

# re: Observer Pattern in F# : Simplified/Enhanced
Requesting Gravatar...
I don't know, I hope Resharper or CodeRush will jump on that soon
Left by Vlad on Jun 23, 2009 3:54 AM

Your comment:
 (will show your gravatar)


Copyright © Erik Araojo | Powered by: GeeksWithBlogs.net