Journal of a software dev

May 24, 2009

Command Query Separation (CQS)

Filed under: best practices, design pattern, oop, software design — Tags: — Michael Cromwell @ 4:58 pm

Introduction

CQS was a term that was coined by Bertrand Meyer and presented itself in his book Object Oriented Software Construction (I haven’t read the book, yet!) the principle states that every method should either be a command that changes state or a query in which case it does not change any state but not both.

In all I agree with the principle I can think of some valid examples that are valid to break it but on the whole it’s makes sense to follow it, however what I want to show in this post is to take this principle and show how it can be applied at various levels rather than just at the method level.

Architectural Level

If we imagine a system which manages lots of amounts of data and the business would like to perform analysis on this data while still providing transactional throughput it would not be uncommon to split the data into separate Online Transaction Processing (OLTP) and Online Analytical Processing (OLAP), this  is a good example of separating the data that will be changing often (OLTP) from the stagnant data that can be analysed (OLAP) I feel this matches strongly to the principle, the benefits gained typically result in better performance and data that reflects the needs of the operations applied to it.

Object Design Level

When we have a complex domain that require numerous behaviours we want to take advantage of domain modelling in our objects by utilising something like DDD to come up with entities, value objects etc… that we can use to represent the domain were working in.

We use these objects to perform transactional operations such as “Submitting an Order” or “Creating a New User” as these represent where we are going to using the behaviours and rules we put together using our objects. What we don’t want to start doing is then using these same objects for displaying result grids on a search screen, this represents a very different usage pattern and if we try to use our objects for this purpose and also for transactional processing we get into a mess quite quickly.

Instead it’s best to take onboard the CQS principle and separate our domain model objects that will be used for out transaction processing from what I think of as reporting or querying objects that are only interested in grabbing data for things such as search screens & reports. So if we were in a issue tracking domain we would probably end up with something like this:

// uses ORM such as nHibernate concerned only with using objects in a transactional
// context does not do any reporting or querying
public class IssueRepository : IIssueRepository
{
	public Issue FindBy(int id)
	{
		// use ORM to get by id
	} 

	public Issue Save(Issue issue)
	{
		// use ORM to save only used when new as object will be tracked
		// for updates automatically
	} 

	public void Delete(Issue issue)
	{
		// use ORM to delete
	}
} 

// probably just uses ADO.NET raw or a light facade on top of ADO.NET
// may use nHibernate but DOES NOT return any transactional objects only
// projections
public class IssueQuerying : IIssueQuerying
{
	public DataTable FindMatchingCriteria(int priorityId, int pageNo, int pageCount, out int virtualCount)
	{
		// use ADO.NET to fill datatable of results, possibly using SP to support paging
		// for older DB
	} 

	public IssueDisplayModel FindAssignedTo(string username)
	{
		// use nHibernate to fill projection object IssueDisplayModel
	}
}

The benefits we get from separating these 2 concerns:

  1. Our domain model objects are not polluted with lots of getters just to be used for reporting/querying
  2. We can utilise databinding because our querying object returns objects that ASP.NET controls know what to do with (one way databinding only)
  3. Our mapping is simplified as we only need to map our domain model objects to other objects for transactional processing needs not querying/reporting.

Summary

Hopefully this post has shown how we can take the original CQS principle and see how it applies to other levels when developing software from the high level architecture right down to the method level.

January 17, 2009

NHibernate & Null Object Pattern: The Options

Filed under: code example, design pattern, nhibernate — Tags: , — Michael Cromwell @ 5:11 pm

Don’t bother using Null Object Pattern

The first option is to just not bother using Null Object Pattern, this is the easiest solution however has the side-effect that you end up with null checks everywhere which is the reason for moving to the Null Object Pattern in the first place.

Place a Null Object in the database

Next option is to have an object in the database that represents the null object so it will probably have an Id of zero and a value of << Unassigned >> or along those lines. This then has its own problems because if it’s a user editable object you don’t really want them to be able to change/delete this data so it becomes a special case that will need to be locked for editing/deleting.

Use Field Access and have the Property Handle the Mismatch

This is my preferred method whereby NHibernate is configured to use field access to the object, and the property handles the mismatch internally for example:

// inside class definition
protected User assignedTo;

public User AssignedTo
{
    get
    {
        return assignedTo ?? User.NotAssigned;
    }
    set
    {
        if (value == User.NotAssigned)
            assignedTo = null;
        else
            assignedTo = value;
    }
}

This gives NHibernate a different view of the assigned to value than outside objects, for NHibernate which uses the internal field assignedTo it can be set to a null however for outside objects that have to use the AssignedTo property it will never be a null and instead will be set to the Null Object in this case User.NotAssigned.

Any other options please add a comment below :-)

November 16, 2008

Staff Intranet Updated

Filed under: best practices, c#, code example, design pattern, oop, software design — Tags: , , , — Michael Cromwell @ 7:45 pm

I just updated the staff intranet project over on codeplex, I have now got it under source control now that they have added support for SVN :) And have also uploaded a new release of the source in case you dont have a source control client compatible.

The changes are:

  • Incorporating some of my other projects (log4net-altconf, object2object mapper) to help with the maintainability of the app.
  • Refactorings I have made to the way a staff member is saved. After gaining a better understanding of DDD principles it was quite clear that the validation around the photo upload & checking for name duplication should be separated as Specification objects to reduce the coupling in the Staff object.

Remember any feedback you can post here on my blog or on codeplex

August 19, 2008

Null Object Pattern by example

I feel sorry for the Null Object pattern, while Abstract Factory Pattern, Strategy and the other patterns from the GoF book get all the attention the Null Object pattern doesn’t get a look in. This is a shame because this pattern can come in very useful, saving you many scattered ==null checks across your code, I’m going to show a real world use of Null Object pattern (and Adapter pattern as a by-product) using example logging objects:

Lets get to it, we have an ILog it looks like this:

public interface ILog
{
    void Debug(string message);
}

Ok granted I have made it a simple example at least it ain’t an ICar or IAnimal ;) how do we get hold of our ILog with an ILogFactory of course:

public interface ILogFactory
{
    ILog GetLog(Type type);
}

We can make this easier to get hold of by having a static gateway so we aren’t having to pass around an ILogFactory to every object or having to new up a ILogFactory instance everytime we want to log:

public static class Log
{
    private static logFactory;

    public static void InitializeWith(ILogFactory logfactory)
    {
	this.logFactory = logFactory;
    }

    public static ILogFactory Current(Type type)
    {
        return logFactory.GetLog(type);
    }
}

You could also leverage a IoC container here instead.

Now we want some implementations I’m a fan of log4net so I would implement the following:

public class Log4NetLogFactory
{
    public ILog GetLog(Type type)
    {
	//retrieve an adapted log4net log something like...
	log4net.ILog rawLog = log4net.LogManager.GetLogger(type);
	return new Log4NetLog(rawLog);
    }
}

With Log4NetLog looking like this:

public class Log4NetLog : ILog
{
    private log4net.ILog log;

    public Log4NetLog(log4net.ILog logToAdapt)
    {
	this.log = logToAdapt;
    }

    public void Debug(string message)
    {
	if (log.IsDebugEnabled)
	    log.Debug(message);
    }
}

Now we want to be able to log in our client code like this:

Log.Current(this.GetType()).Debug("some debug message");

The problem of course is that if we try to do this without hooking up our static Log class to an ILogFactory we get the dreaded null reference exception, this is bad! Our logging code should not throw exceptions, enter the Null Object pattern:

public static class Log
{
    private static logFactory = new NullLogFactory();

    public static void InitializeWith(ILogFactory logfactory)
    {
	if (logFactory != null)
	    this.logFactory = logFactory;
    }

    public static ILogFactory Current(Type type)
    {
        return logFactory.GetLog(type);
    }
}

We instantiate a new NullLogFactory object and assign it to the static logFactory member, we also perform a check to make sure no nulls are sent to the InitializeWith method, here is the NullLogFactory:

public class Log : ILogFactory
{
    public ILog GetLog(Type type)
    {
        return new NullLog();
    }
}

All this does is new up a NullLog object:

public class NullLog : ILog
{
    public void Debug(string message)
    {
    }
}

The NullLog does nothing whatsoever apart from prevent us from receiving null reference exceptions, the neat thing about this though is that we could potentially capture attempts to call methods the NullLog and perform some sort of internal debugging:

public class NullLog : ILog
{
    public void Debug(string message)
    {
        if (Config.IsInternalDebugEnabled)
            Debug.Write("'{0}' sent to NullLog", message);
    }
}

That way users of the logging objects can be notified if logging has taken place but a log factory has not been hooked up.

June 27, 2008

New Staff Intranet Release

I have found enough spare time to put up a new release of the staff intranet project, for those who are not aware of this project it is a demonstration of using best practices, principles & patterns in a real world web application so if your looking for pointers or some code to use for your own applications go give it a look on codeplex.

In this newest version I have added AOP support to cut down on cross cutting code and also the ability to delete staff members from the GridView, most of the time spent was fighting against the asp.net controls (suprise, surprise) such as the GridView and the ObjectDataSource, I’m not sure what the guy(s) who created the ObjectDataSource object was smoking at the time but it must have been stronger than just tobacco :-)

My next release I want to demonstrate adding some service support showing how we can re-use existing code so they become little more than a remote facade (in theory!).

May 28, 2008

Head First Series

Filed under: advice, books, design pattern, oop, software design — Tags: , , , — Michael Cromwell @ 11:18 am

I’m just over half way through Head First Software Development, and I have it found a fantastic book, to be honest I wasn’t surprised by this conclusion, I have read both HFDP and HFOOAD and was blown away by the qualities this series has.

By moving away from the mostly dreary dull literature we find in most books about software development and instead keeping the tone light and amusing, using various visual elements on the page & including user input activities I have found them incredibly helpful in getting the message through and making it stick (not easy when the topics covered are tricky and complicated).

I would highly recommend anyone to give this series a shot, you won’t be disappointed!

 

May 10, 2008

Staff Intranet on Codeplex

I have not posted here for a little the main reason being I have been putting the final touches to another project I have been working on in my spare time, it’s a staff intranet application what I have tried to do with this project as with the previous projects is try and use it as a learning exercise, so I have incorporated some best practices and design patterns and used them for a real world example, in there you will find:

  • Inversion of control – This has been decoupled from a particular IoC container but I have utilised Castle Windsor under the hood
  • TDD/BDD - Around 98% of the behaviour of the application was designed test first, the reason I have put BDD as well is because I like to think of my tests as defining the behaviour of the application rather than of just testing assertions in my code, this comes out through the naming of my test cases
  • NHibernate – This was my first use of NHibernate and overall I was very pleased with what this very powerful ORM gives you and also keeping the domain clean from database artifacts (persistence ignorance)
  • Model View Presenter - This is the first time I have emplyed model view presenter for web and it acts as a nice interim between moving logic from the codebehind and going the whole hog and using an MVC framework such as monorail or ASP.NET MVC, I’m completely sold on having tests against the UI logic
  • SQL Server 2005 – This was probably the most dissapointing aspect of developing this application, I was hoping that the new client tools would be great and easy to get stuff done with however I found it the opposite things that used to be easy using the SQL server 2000 enterprise manager were not intuituve at all with the Management Studio, examples:
    • Wanting to remove a database that already exists
    • Setting permissions from the users perspective

Anyway after that intro you can find more details over at my project homepage on codeplex.

My hope is that this project will help others who are learning about the above but would like to see them used in a real world context rather than just in hello worls context.

March 21, 2008

Multi Search Engine Enhancement Using Design Patterns

Filed under: .net, advice, c#, code example, design pattern, oop, refactoring, software design — Tags: , , — Michael Cromwell @ 12:08 pm

Before reading it might be worth having a look at my previous post on this mini project, the current structure looks like this:

Current Class Structure

As you can see it is fairly straight forward to plugin your own SearchEngine implementation, either by taking advantage of the AbstractSearchEngine or by implementing the ISearchEngine interface.

In both cases the client wanting to plugin their custom searchengine implementation only needs to concentrate on writing code to extract search results from the searchengine they are querying.

One of the problems at the moment is that the searches are performed synchronously which could potentially make the UI un-responsive if the query takes a while, this is a big no-no, so ideally I would like to make the calls asynchronously and then the UI (or any other listening object) can be notified when results are returned.

We could start by making some changes to the structure:

Updated Structure V1

Now we have introduced a new method SearchAsync and also a new event SearchCompleted we have also introduced the same to the AbstractSearchEngine class, there are some issues with these changes:

  1. This could be a first sign of polluting an interface unrelated responsibility – Any client who wants to plug in their own searchengine cannot just concentrate on implementing code to bring back results from a searchengine, they must now implement a asynchronous searching strategy.
  2. Using this approach as stated above we have made it the clients responsibility to add the asynchronous code this could bring about some issues such as the client just not bothering and instead just making a synchronous call to the searchengine or badly implemented asynchronous code that may use threading badly.
  3. There may already be quite a few implemented searchengines that rely on this interface by making this change we are breaking there compatibility with ISearchEngine for a change that may not be affecting them at all

We need to think of another way… We already have a nicely defined ISearchEngine interface which we know we can call into and it will bring back results and allow us to navigate those results, the only thing we are adding is the extra behaviour to perform the calls asynchronously ideally we would like to add this behaviour without effecting what we have already! Enter Decorator stage right :)

The intent of the decorator is to add behaviour dynamically to existing objects which is what were after, So lets come up with an alternative structure:

Updated Structure V2

We now have a brand new class irrelevant fields have been omitted which takes the ISearchEngine in its constructor in most cases this new class will delegate calls straight through to the decorated class however if a search is in progress it needs to take other actions. Using TDD I came up with the class below:

public class AsyncSearchEngineDecorator : ISearchEngine
{
 private delegate void PagingDelegate();
 private delegate void SearchingDelegate(string SearchString);

	private ISearchEngine decoratedSearchEngine;
 private volatile bool resultsReturned = false;
 private readonly object locker = new object();

	public event EventHandler SearchComplete;

	private void SetResultsReturnedTo(bool value)
 {
 	lock (locker)
 	{
 		resultsReturned = value;
 	}
 }

	private bool ResultsReturnedValue()
 {
 	lock (locker)
 	{
 		return resultsReturned;
 	}
 }

	public AsyncSearchEngineDecorator(ISearchEngine searchEngineToDecorate)
 {
 	if (searchEngineToDecorate == null)
 		throw new ArgumentNullException("searchEngineToDecorate", "searchEngineToDecorate cannot be null");

		this.decoratedSearchEngine = searchEngineToDecorate;
 }

	public void Search(string searchText)
 {
 	SetResultsReturnedTo(false);

		PerformAsync(new SearchingDelegate(delegate(string text)
 	{
 		decoratedSearchEngine.Search(text);
 	}), new object[] {searchText});
 }

	private void RaiseSearchComplete()
 {
 	if (SearchComplete != null)
 		SearchComplete(this, EventArgs.Empty);
 }

	public string Name
 {
 	get { return decoratedSearchEngine.Name; }
 }

	public bool HasResults
 {
 	get {
 		if (ResultsReturnedValue())
 			return decoratedSearchEngine.HasResults;
 		else
 			return false;
 	}
 }

	public IList Results
 {
 	get {
 		if (ResultsReturnedValue())
 			return decoratedSearchEngine.Results;
 		else
 			return new List();
 	}
 }

	public void NextPage()
 {
 	if (ResultsReturnedValue())
 	{
 		PerformAsync(new PagingDelegate(delegate
 		{
 			decoratedSearchEngine.NextPage();
 		}));
 	}
 	else
 		RaisePagingWhileSearchInProgressException("NextPage");
 }

	public void PreviousPage()
 {
 	if (ResultsReturnedValue())
 	{
 		PerformAsync(new PagingDelegate(delegate
 		{
 			decoratedSearchEngine.PreviousPage();
 		}));
 	}
 	else
 		RaisePagingWhileSearchInProgressException("PreviousPage");
 }

	private static void RaisePagingWhileSearchInProgressException(string method)
 {
 	throw new InvalidOperationException(string.Format("{0} cannot be called while search is in progress", method));
 }

	public int PageSize
 {
 	get
 	{
 		return decoratedSearchEngine.PageSize;
 	}
 	set
 	{
 		decoratedSearchEngine.PageSize = value;
 	}
 }

	public int CurrentPage
 {
 	get {
 		if (ResultsReturnedValue())
 			return decoratedSearchEngine.CurrentPage;
 		else
 			return -1;
 	}
 }

	private void PerformAsync(Delegate action)
 {
 	PerformAsync(action, null);
 }

	private void PerformAsync(Delegate action, object[] args)
 {
 	SetResultsReturnedTo(false);

		ThreadPool.QueueUserWorkItem(delegate
 	{
 		action.DynamicInvoke(args);
 		SetResultsReturnedTo(true);
 		RaiseSearchComplete();
 	});
 }
}

If there is any issues with the threading code please give me heads up :) Now in my UI I can use the new class as so:

searchEngine = new AsyncSearchEngineDecorator(searchEngine);
searchEngine.SearchComplete += new EventHandler(HandleSearchPerformed);

You may thinking at this point… “hang on you class diagram looks nothing like the class diagram from the GoF book” …and you would be right, one mistake that some people can make when learning about design patterns is that the structure of your implementation must match the structure shown, this is not the case there are many ways to implement a design pattern I too got hung up on using the class diagram as a template for how design patterns should be created, however I read a chapter from Refactoring to Patterns that brought it into perspective that if you need to introduce a design pattern then implement it in the best way for your surroundings not the best way according to a class diagram from GoF or some design patterns website.

So what have we ended up with, well we have created a new class which has the responsibility of making calls against an ISearchEngine aysnchronously by doing this we have kept both the ISearchEngine and AbstractSearchEngine responsibilities to be just concerned with pulling results back from a custom searchengine. The changes to the UI have been minimal it simply wraps the existing searchEngine into the new AsyncSearchEngineDecorator object and handles the SearchComplete event.

January 30, 2008

A Path for learning Object Oriented Programming

Filed under: advice, design pattern, oop, software design, tips — Michael Cromwell @ 8:04 pm

Fundamental concepts of OOP

One of the first items that should be introduced when first embarking on learning OOP is the concept of PIE:

Polymorphism
Inheritance
Encapsulation

Polymorphism

In OOP the term polymorphism refers to the action of an class that derives from other class(es) and can perform the behaviour of it’s base classes or define new behaviour (representing more than one type).
For more information I recommend visiting the MSDN Polymorphism C# Programming Guide

Inheritance

The act of deriving an class from an existing class, the derived class can be referred to as the subclass with the class that was derived from being referred to as the superclass.

Inheritance can be thought of as an “is-a” relationship, for more information visit the MSDN Inheritance C# Programmers Guide

Encapsulation

Encapsulation hides the details of how an object performs behaviour, by protecting our users from knowing how an object works they can simply use the object without having to obtain details of it’s inner workings. This has a number of benefits:

  • The object is easier to work with
  • If the inner workings change, the user should not need to change

More information can be found on wikipedia

Once we have learned these concepts the next challenge is knowing how to apply them effectively.

Principles of Class Design

A lot of times people ask how to get better at designing OO systems and the responses usually involve the person studying design patterns, however I believe that more use can be gained by studying the principles of class design, these are the principles that are at the core of each of the design patterns.

The principles of class design was compiled by OO guru Robert C. Martin in the book Agile Software Development, Principles, Patterns, and Practices This is one of the best books I own and if you don’t own a copy I highly recommend it getting one!

The 5 principles are:

OCP – Open Closed Principle
SRP – Single Responsibility Principle
LSP – Liskov’s Substitution Principle
DIP – Dependency Inversion Principle
ISP – Interface Segregation Principle

These principles should not been seen as principles that should be followed 100% as you will see it is near impossible to do so however should be seen as principles we should try to adhere to as much as possible.

OCP

OCP was coined by Bertrand Meyer, it states that a class should be closed modification while open for extensibility, main ways to achieve this involve making good use of abstractions by allowing changes to made via subclasses or overriding method behaviour.

SRP

SRP states that a class should have one, and only one, reason to change, this can be achieved by separating out responsibility to appropriate objects (highly cohesive classes) and to not have one class perform varied activities.

LSP

LSP was coined by Barbara Liskov and at it’s core states that a derived class should be substitutable with it’s base class, an example of not conforming to this is by misuse of inheritance.

If we take an example of a rectangle class and say we want to add another shape class of square we could inherit from the existing rectangle class however the behaviour of a square does not conform to that of a rectangle (a rectangle can have varying heights and widths, a square cannot), if a user changes the height of a rectangle the width will unaffected however if we changed to the height against a square we would also need to change the width to match.

Dependency Inversion Principle

DIP states that we should depend upon abstractions and not depend on concrete types, this is in practice impossible in all cases as we need to create an instance of a class at some point. However by depending on abstractions rather than concrete classes (some design patterns help accomplish this) we make our code more loosely coupled and protects us from the most feared word in software design “change” :)

Interface Segregation Principle

ISP can be thought to relate to SRP if a class has a very large interface it will generally trying to perform too much work, a side-effect of not conforming to this principle is that clients that only use a subset of a very large interface are at risks to changes in other areas of the same interface, by breaking the interface up we can reduce the likelihood that a client will be affected by changes to the interface.

Design Patterns

Design patterns in OOP are a collection of recurring software designs that can be applied into common scenarios and assigned a name.

The most common set of design patterns are known as the GoF (Gang of Four) design Patterns this book can be a difficult read when first learning about design patterns, instead I would recommend using GoF Design Patterns as a reference and instead getting a copy of Head First Design Patterns this is an excellent book and even covers some of the principles shown above. You can also visit dofactory.com which has lots of examples of the GoF design patterns in C#

January 26, 2008

Syntax Trees using Composite/Intepreter Pattern Part 3

Filed under: .net, c#, code example, design pattern, oop, refactoring, software design — Michael Cromwell @ 9:02 pm

Part 1

Part 2

Where we left off last time we had 2 leaf nodes that peformed operations against two operands (LessThanWhere & EqualToWhere) now I want to add a composite class to perform some logical operations.

Creating the Composite Class

Like before we will drive out the requirements TDD style:

[Test]
public void Should_add_multiple_and_where_clause_with_string_value_on_BuildQuery()
{
	string expected = "WHERE ((col1 = 'test') AND (col2 = 'test2'))";
	SelectQueryBuilder queryBuilder = new SelectQueryBuilder();
	EqualToWhere where1 = new EqualToWhere("col1", "test");
	EqualToWhere where2 = new EqualToWhere("col2", "test2");
	queryBuilder.AddWhere(new AndWhere(where1, where2));

	string output = queryBuilder.WhereSection();
	Assert.AreEqual(expected, output);
}

Now we need to add the new class to get compilation:

 public class AndWhere : AbstractWhere
{
	public AndWhere(AbstractWhere left, AbstractWhere right)
	{
	}

	public override string Output()
	{
		return "";
	}
}

It should now compile so we run the tests and get a fail, lets go and make them pass:

public class AndWhere : AbstractWhere
{
	AbstractWhere left;
	AbstractWhere right;

	public AndWhere(AbstractWhere left, AbstractWhere right)
	{
		this.left = left;
		this.right = right;
	}

	public override string Output()
	{
		StringBuilder output = new StringBuilder();
		output.Append("(");
		output.Append(left.Output());
		output.Append(" AND ");
		output.Append(right.Output());
		output.Append(")");

		return output.ToString();
	}
}

This class expects 2 operands to be passed in, the only constraint being that they derive from the AbstractWhere class, when the SQL is built in the Output method the ANDWhere class simply delegates off to the left and right operands respectively, We should now have a green tick for the test above.

Full control over SQL produced

I won’t show the implmentation for an ORWhere class as I’m sure you can guess how it can be implemented instead I will show how we can use the classes we have now to produce SQL under our control i.e. nested SQL:

[Test]
public void Should_add_multiple_and_nested_or_where_causes_with_string_values_on_BuildQuery()
{
	string expected = "WHERE ((col1 = 'test') OR ((col2 = 'test2') AND (col3 = 'test3')))";

	SelectQueryBuilder queryBuilder = new SelectQueryBuilder();

	EqualToWhere where1 = new EqualToWhere("col1","test");
	EqualToWhere where2 = new EqualToWhere("col2", "test2");
	EqualToWhere where3 = new EqualToWhere("col3", "test3");
	AbstractWhere andWhere = new AndWhere(where2, where3);
	queryBuilder.AddWhere(new OrWhere(where1, andWhere));

	string output = queryBuilder.WhereSection();
	Assert.AreEqual(expected, output);
}

We can now build up a nice tree of the syntax we would like to use as our SQL without having to worry about levels, What we have from the above can be viewed as:

SQL Syntax Tree Example

Handling other kinds of Operands

In part 1 I made reference to a question that was posted on the SelectQueryBuilder codeproject page in which the poster asked if it would be possible to use functions as part of the where clause:

WHERE DATEDIFF(dd,col1,'20080101') >= 0

One problem is that this function is a SQL server function making the above SQL constrained to SQL server, so before implementing the above into our code we need to keep in mind that we are limiting the SQL generation to SQL server, so if we accept this constraint we could try the following:

[Test]
public void Should_add_single_explicit_function_with_equals_on_BuildQuery()
{
	string expected = "WHERE (DATEDIFF(dd,col1,'20070101') = 0)";
	SelectQueryBuilder queryBuilder = new SelectQueryBuilder();

	FunctionWhere functionWhere = new FunctionWhere("DATEDIFF", "dd", "col1", "'20070101'");
	EqualToWhere equalFunctionWhere = new EqualToWhere(functionWhere, 0);
	queryBuilder.AddWhere(equalFunctionWhere);

	string output = queryBuilder.WhereSection();
	Assert.AreEqual(expected, output);
}

Ok, so lets get that test compiling, firstly we need to add the new FunctionWhere class:

public class FunctionWhere : AbstractWhere
{
	public FunctionWhere(string name, params string[] args)
	{
	}

	public override string Output()
	{
		return "";
	}
}

Next we also need to allow EqualToWhere to accept an overloaded constructor that can accept an AbstractWhere:

public EqualToWhere(AbstractWhere where, object rightSide)
	: this(where.Output(), rightSide)
{
}

This neat we can simply chain the constructor by calling the Output method on the where object passed in.Now to get the test to pass we need to make create the implementation code in FunctionWhere:

public class FunctionWhere : AbstractWhere
{
	private string name;
	private string[] args;

	public FunctionWhere(string name, params string[] args)
	{
		this.name = name;
		this.args = args;
	}

	public override string Output()
	{
		StringBuilder output = new StringBuilder();
		output.Append(name);
		output.Append("(");

		foreach (string arg in args)
		{
			output.Append(arg);
			output.Append(',');
		}

		output.Remove(output.Length - 1, 1); // strip last comma
		output.Append(")");

		return output.ToString();
	}
}

I have gone for the approach of simply passing the function name then passing the arguments in, this could easily be changed to be more specific i.e. using a DateDiffWhere however the FunctionWhere performs what we need to for now.

Closing Notes

I hope this series of articles have provided some help on understanding how we can use patterns to refactor existing code one thign to note is that throughout all these changes I have not once had to re-open the SelectQueryBuilder class all the modifications where made externally which is inline with the OCP coined by Bertrand Meyer.

If your after a great book on refactoring to patterns I recommend Refactoring to Patterns by Joshua Kerievsky, I have recently read it and it is what inspired me to create this series.

Older Posts »

Blog at WordPress.com.