Thursday, 12 August 2010

Enum Replacement Pattern

I'm sure you've come accross the feeling that although they are handy at first enums have limitations when it comes to OOP.

Here is an implementation that gives you the goodness of enums, having a set of named items that identify things, and adds encapsulation of functionality which I've always felt enums lack.

Lets start off with a simple implementation that represents a time interval (Months and Weeks) that we will use in our domain.




This is simple enough, easy to write and easy to use. However things quickly get more complicated once you start to use this enum. Lets say that we now need to be able to create a TimeSpan that represents one of these intervals from a given DateTime. 



The code does not smell great. It violates single resposibility for a start. It also it not very object orientated, living in its own static class like that. Lets see what can we do to improve this situation.

I'm going to approach this problem by avoiding enums all together. First we create a class that represents the basic concept:



Quite a bit more code for not much benefit at this stage but lets talk about what's happening here.

First notice the private constructor. Only this class can create instances of itself. So the two public static readonly fields are the only two instances of this class ever. This means we can use the standard implmentation of == to compare variables that hold these values. Just like an enum




So far this is just like what we had before. However it gets more interesting when we want to add the functionality for computing offsets from a given date. Because this is a class we can use standard OOP tricks like polymorphisim to encapsulte the functionality.



So now I've made DurationInterval abstract and created two subclasses. Each one encapsulates one way of calculating the date offset. I have had to make the constructors of the Subclasses public. This brakes some of the encapsulation and introduces the possibility that someone could new up an instance on MonthInterval breaking the control over the number of instances in the AppDomain.

We could remedy this be moving the subclasses into DurationInterval and although I think that is kind of cool I try to avoid nested classes in production code. There is an even better solution but I'll save that for the next post on this subject.

In the mean time lets take a step back and see what we've created. Our GetDateFrom method from before would now look like this.



All the calculation is palmed off the the interval itself. At this point we could go and inline all calls to this method as its trivial and its implementation reads better than the method call would.

Hope you found this useful. In future posts I'll show how to make this work properly with serialization, across the wire and to the DB.

Any comments, questions or suggestions please post them bellow.


Share and enjoy.

Wednesday, 11 August 2010

Forays in the Binary Serializer

I am currently working on some code that I'm hoping will become a tool that is able to view the output of .Net's BinarySerializer.

First a bit of background. I use Windows Workflow Foundation (WF) at my work and serialize its state to the database. As time has gone on and we have had different versions of the workflows and the objects they depend upon we have sometimes had problems deserializing older versions of workflows (I will do another post that will go in to the pitfalls and issues I'm talking about here).

To cut a long story short the error reporting of the BinarySerializer leaves much to be desired. Have you ever had something like: "Error deserializing a serializable property." and wished you could know anything about the context? The name of the property would be a great start.

Anyway after getting this one to many times and spending days finding a problem that was down to an assembly version not being updated I decided to look into being able to view the serialized data without being able to deserialize it.

All I could find was this document by Lluis Sanchez Gual. Who from what I can tell has figured out the format of the BinaryFormatter by brute force for the Mono Project. So I started writing a viewer from scratch. I am using Boo for no other reason than I want to learn it.

Over the next few posts I'll be sharing my findings and experiences while doing this. Hopefully there will be someone how finds this informative or even useful. At the very least this will be a place that I can came back to later to see what I was thinking.

Share and enjoy.