Categories
Programming

Using full observer pattern instead of events

Note: I have transferred this blog from my old blog site: http://dcarapic.blogspot.com/ so I am reposting most of the stuff from there

Wikipedia (at the time of this writing) defines Observer pattern as following:
The Observer pattern (a subset of the asynchronous publish/subscribe pattern) is a software design pattern in which an object, called the subject, maintains a list of its dependents, called Observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.

MSDN defines Events (I refer to it later as 'eventing system') as:
Events enable a class or object to notify other classes or objects when something of interest occurs. The class that sends (or raises) the event is called the publisher and the classes that receive (or handle) the event are called subscribers.

.NET eventing system is nothing else then an implementation of an Observer pattern. The subject (type that defines an event) raises the event to notify the Observer (class which adds a handler to the event) that something has occurred.
Having the Observer pattern integrated into the language is a great thing which enables the developer to easily add notifications about object changes. However there are cases where this kind of a system is not sufficient and may lead to poorly designed code if you use it.

The .NET eventing system has the following drawbacks:

  • You must define each 'change' as a separate event. Although there are some events which go around this by trying to be 'generic' (such as INotifyPropertyChanged.PropertyChanged) they are usually not elegant and seem more like a workaround.
  • You should define each event as EventHandler (or EventHandler<>). This is not mandatory as CLR allows you to define events of any method signature but if you plan on being CLS compliant and not getting compiler warnings then you usually should follow this convention.

In most cases these drawbacks are not serious and they do not affect your code quality that much. But there are some cases (especially when you have objects where there are lots of changes of various types) where the eventing system is just not good enough. For such cases you should build you own custom Observer pattern.

Building you own Observer pattern is quite simple and can be expressed in these few steps:

  1. Select the type which will be the subject (lets call it Subject)
  2. Define the changes that this type will expose
  3. Create a new interface which will define methods that represent the changes of the Subject (for example ISubjectObserver)
  4. Create a new interface method for each change (for example OnSubjectNameChanged, OnSubjectTypeChanged, OnSubjectDetailLineAdded etc.) with parameters which are suitable for each notification (old value, new value, added detail object etc.)
  5. Create a new type which will represent the Observer (lets call it Observer)
  6. Have it implement the new interface (public class Observer: ISubjectObserver)
  7. Implement the methods of the interface
  8. Add two methods to the Subject type which will be used to register/unregister an Observer (RegisterSubjectObserver(ISubject**Observer**),UnRegisterSubjectObserver(ISubjectObserver*)`

Looks simple, and it is. If you are reading this you are probably thinking "hey, I know how to do all this". Well that might be true but developers sometimes forget to think about alternate ways to do something and this might give you another way of looking at things when designing your applications.

Categories
Programming

Using “hole in the middle” pattern with methods to insure pre and post processing

Note: I have transferred this blog from my old blog site: http://dcarapic.blogspot.com/ so I am reposting most of the stuff from there

Sometimes it is important to do processing before and after executing a piece of code (or a function). This is usually necessary when you have unmanaged components that you wish to use. C# solves this by using the using keyword. Example of this would be the various ASP.NET connections.

var connectionString = GetConnectionString();
using (var adapter = new SqlConnection(connectionString))
{
    // do something
}

While using using is a good solution it does require the programmer to be disciplined and not to forget it. Another drawback of this solution is that requires that you have a component which implements IDisposable and you must always instantiate it in order to use it.
Another possible solution would be to use "hole in the middle pattern" to achieve the similar functionality. In short "hole in the middle" refers to having some sort of activity/processing where a part of processing is provided by an external source and this is exactly what we need.

We need to ensure that we will execute some code before and after the 'main' code gets executed. Here is how we could organize the code so that we ensure that SqlConnection gets properly disposed

public static class ContinuationTest1
{
    public static void ExecuteSql(Action methodToExecute)
    {
        var connectionString = GetConnectionString();
        using (var adapter = new SqlConnection(connectionString))
        {
            methodToExecute(adapter);
        }
    }
}

Using this new method is relatively simple

public void UseContinuationTest1()
{
    ContinuationTest1.ExecuteSql((con) =&gt;
    {
        con.CreateCommand();
        // do something
    });
}

Note that I am using new Lambda style method definitions as it makes this sort of programming style really easy to use. Here is another example of how we could achieve exception wrapping

public static void ExceptionWrap(Action methodToExecute)
{
    try
    {
        methodToExecute();
    }
    catch (Exception ex)
    {
        var exceptionHandler = GetExceptionHandler();
        exceptionHandler.Handle(ex);
    }
}

Using it is, again, simple

public void UseContinuationTest2()
{
    ContinuationTest2.ExceptionWrap(() =&gt;
    {
        // do something that might throw an exception
    });
}

Another advantage that we get from this is that we can hide the creation of parameters that we provide to our "method in the middle". This could be used as (simple) (or with) Dependency Injection mechanism where we want to ensure a consistent way to access components or services in our code. Here is a variant of the first example where we do not provide the SqlConnection but rather an interface (IDbConnection). I have also added a variant where we can ensure that everything is done inside a transaction.

public static class ContinuationTest3
{
    public static void ExecuteSql(Action methodToExecute)
    {
        var connectionString = GetConnectionString();
        using (var adapter = new SqlConnection(connectionString))
        {
            methodToExecute(adapter);
        }
    }
    public static void ExecuteSqlInTransaction(Action methodToExecute)
    {
        using (var ts = new TransactionScope())
        {
            ExecuteWithAdapter(methodToExecute);
            ts.Complete();
        }
    }
}

And using it

public void UseContinuationTest3()
{
    ContinuationTest3.ExecuteSqlInTransaction((con) =&gt;
    {
        con.CreateCommand();
        // do something, transaction will be automaticaly commited
    });
}

While this kind of programming looks great, there are some drawbacks to it if you are using the Lambda style methods to define the "middle method" that will get executed. Drawbacks with Lambdas are: Uglier stack trace - Lambda is just a nicer way to define an inline method. It is still a method and the C# compiler will give it an ugly name Method inside a method - This might be the a subjective issue to some. Wherever you are using this style you will need to have two methods, the outside method and the "middle" method.
Using Lambdas makes the "middle" method look like it is not there, but it still is. Variable in outer scope - Make sure that you understand what happens if you use an outer scope variable inside the lambda method. This is something that is good to know in general 🙂 I hope that you can see that the power that we can get from this style of programming.