Design patterns and practices in .NET: the Builder pattern

Introduction

According to the standard definition the Builder pattern separates the construction of a complex object from its representation so that the same construction process can create different representations. This is probably difficult to understand at first as is the case with most pattern definitions.

We have a complex object to start with. The construction is the process, i.e. the logic and its representation is the data, so we’re separating the logic from the data. The reason why we separate them is that we want to be able to reuse this logic to work with a different set of data to build the same type of thing. The only difference is going to be the data. So the basic rule is simple: separate the data from the logic and reuse that logic.

Imagine a restaurant with no set menus. The process of ordering food can become a tedious dialog with the waiter: what kind of cheese would you like? What types of ingredient? What type of side-dish? This conversation can go on and on especially if the food you’d like is complex. And if you come back the following day to order then you’ll go through the same dialog. It would be a lot easier to pick your lunch off of the menu, right?

You may have such dialogs in your code where your backend code asks the client for all the “ingredients”, i.e. all the parameters necessary to construct an object. The next step you may take is to put all those parameters into the constructor of the object resulting in a large constructor. Within the constructor you might have extra code to construct other objects, check the validity and call other objects like services to finally construct the target object. This is actually a step towards the Builder pattern: we send in the ingredients to build an object. The construction logic of the object will be the same every time, but the data will be different. To apply this to the restaurant example we can imagine that the restaurant sells pasta-based dishes and customers come in with their ingredients list. They then give that list to the chef who will then “build” the pasta dish based on the ingredients, i.e. the parameters. The construction process will be the same every time, it is the “data” that is different. The customer will not tell the chef HOW to prepare the dish, only what should constitute that dish. The customer will not even know the steps of making the dish. The ingredients list replaces the dialog: whenever the chef has questions he or she can consult the list to get your inputs.

Demo

Let’s start with a BAD example. Open Visual Studio and create a console application. We’ll simulate a custom made graphing solution which requires a lot of parameters. Insert a new class called ClassyGraph:

public class ClassyGraph
	{
		private List<double> _primarySeries;
		private List<double> _secondarySeries;
		private bool _showShadow;
		private bool _largeGraphSize;
		private double _offset;
		private GraphType _graphType;
		private GraphColourPackage _colourType;

		public ClassyGraph(List<double> primarySeries, List<double> secondarySeries, 
			bool showShadow, bool largeGraphSize, double offset, 
			GraphType graphType, GraphColourPackage colourType)
		{
			_primarySeries = primarySeries;
			_secondarySeries = secondarySeries;
			_showShadow = showShadow;
			_offset = offset;
			_largeGraphSize = largeGraphSize;
			_graphType = graphType;
			_colourType = colourType;
		}

		public override string ToString()
		{
			StringBuilder sb = new StringBuilder();
			sb.Append("Graph type: ").Append(_graphType).Append(Environment.NewLine)
				.Append("Colour settings: ").Append(_colourType).Append(Environment.NewLine)
				.Append("Show shadow: ").Append(_showShadow).Append(Environment.NewLine)
				.Append("Is large: ").Append(_largeGraphSize).Append(Environment.NewLine)
				.Append("Offset: ").Append(_offset).Append(Environment.NewLine);
			sb.Append("Primary series: ");
			foreach (double d in _primarySeries)
			{
				sb.Append(d).Append(", ");
			}
			sb.Append(Environment.NewLine).Append("Secondary series: ");
			foreach (double d in _secondarySeries)
			{
				sb.Append(d).Append(", ");
			}
			return sb.ToString();
		}
	}

	public enum GraphType
	{
		Bar
		, Line
		, Stack
		, Pie
	}

	public enum GraphColourPackage
	{
		Sad
		, Beautiful
		, Ugly
	}

We use this in the Main method as follows:

static void Main(string[] args)
{
	ClassyGraph graph = new ClassyGraph(new List<double>() { 1, 2, 3, 4, 5 }, 
		new List<double>() { 4, 5, 6, 7, 8 }, true, false, 
		1.2, GraphType.Bar, GraphColourPackage.Sad);
	Console.WriteLine(graph);
	Console.ReadKey();
}

There’s nothing complicated in this code I believe. However, it has some issues. We’ve got our nice ClassyGraph which has a big constructor with 7 parameters. You’ll see a construction example in Main and with so many parameters it can be confusing which one is which, which ones are needed, which ones can be null or empty, what the order is etc. You can see such constructors in old code where the object just kept growing and new parameters were introduced to accommodate the changes. Also, such classes typically have multiple constructors that are chained together with some defaults. This can become a real mess: which constructor should we call? When?

Run the application and you’ll see the output in the console, so at least the application performs what it’s supposed to.

One immediate “solution” is to get rid of the constructor and change your private variables into public properties like this:

public List<double> PrimarySeries{get;	set;}
public List<double> SecondarySeries { get; set; }

Then the caller defines the attributes through the property setters:

ClassyGraph cg = new ClassyGraph();
cg.PrimarySeries = new List<double>() { 1, 2, 3, 4, 5 };
cg.SecondarySeries = new List<double>() { 4, 5, 6, 7, 8 };

We at least solved the problem of the large constructor. If you call the property setters instead then the code is a bit cleaner as you actually see what “true” and “1.2” mean just by looking at the code. Here comes the revised code so far:

public class ClassyGraph
	{
		public List<double> PrimarySeries{get;	set;}
		public List<double> SecondarySeries { get; set; }
		public bool ShowShadow{get;	set;}
		public bool LargeGraphSize{get;	set;}
		public double Offset{get;	set;}
		public GraphType GraphType{get;	set;}
		public GraphColourPackage ColourType { get; set; }

		public override string ToString()
		{
			StringBuilder sb = new StringBuilder();
			sb.Append("Graph type: ").Append(GraphType).Append(Environment.NewLine)
				.Append("Colour settings: ").Append(ColourType).Append(Environment.NewLine)
				.Append("Show shadow: ").Append(ShowShadow).Append(Environment.NewLine)
				.Append("Is large: ").Append(LargeGraphSize).Append(Environment.NewLine)
				.Append("Offset: ").Append(Offset).Append(Environment.NewLine);
			sb.Append("Primary series: ");
			foreach (double d in PrimarySeries)
			{
				sb.Append(d).Append(", ");
			}
			sb.Append(Environment.NewLine).Append("Secondary series: ");
			foreach (double d in SecondarySeries)
			{
				sb.Append(d).Append(", ");
			}
			return sb.ToString();
		}
	}

	public enum GraphType
	{
		Bar
		,Line
		,Stack
		, Pie
	}

	public enum GraphColourPackage
	{
		Sad
		,Beautiful
		, Ugly
	}
static void Main(string[] args)
{
        ClassyGraph cg = new ClassyGraph();
        cg.PrimarySeries = new List<double>() { 1, 2, 3, 4, 5 };
        cg.SecondarySeries = new List<double>() { 4, 5, 6, 7, 8 };
	cg.ColourType = GraphColourPackage.Sad;
	cg.GraphType = GraphType.Line;
	cg.LargeGraphSize = false;
	cg.Offset = 1.2;
	cg.ShowShadow = true;
	Console.WriteLine(cg);
	Console.ReadKey();
}

We have solved one problem but created another at the same time. The caller has to remember to call all these properties, keep track of which ones are already set, in what order etc. The code is certainly easier to read but you might forget to set some of the properties. Also, we are not controlling the order in which the properties are set. It may be an important part of the logic to set the series before the graph type or vice versa. With public properties this is difficult to achieve. The caller may miss some important property so that you have to introduce a lot of validation logic: “don’t call this yet, call that before”, “you forgot to set this and that” etc.

Let’s see how a builder object can solve this. Add a new class called GraphBuilder to the project:

public class GraphBuilder
{
	private ClassyGraph _classyGraph;

	public ClassyGraph GetGraph()
	{
		return _classyGraph;
	}

	public void CreateGraph()
	{
		_classyGraph = new ClassyGraph();
		_classyGraph.PrimarySeries = new List<double>() { 1, 2, 3, 4, 5 };
		_classyGraph.SecondarySeries = new List<double>() { 4, 5, 6, 7, 8 };
		_classyGraph.ColourType = GraphColourPackage.Sad;
		_classyGraph.GraphType = GraphType.Line;
		_classyGraph.LargeGraphSize = false;
		_classyGraph.Offset = 1.2;
		_classyGraph.ShowShadow = true;
	}
}

So now we encapsulate the graph creation in a builder where we can control the properties, their order etc. The caller doesn’t need to remember the steps and worry about forgetting something.

You can think of this builder as a meal on a menu. One option is that you take a recipe about how to make a lasagne to a restaurant. You will then tell the chef to get some eggs, flour, oil, make the dough, so on and so forth. That’s like setting the properties of an object one by one. Alternatively you can open the menu and tell the chef that you want a lasagne. He is a lasagne builder and will know how to make it. The GraphBuilder class builds a very specific type of graph – just like asking for a lasagne will get you a very specific type of dish, and not, say, a hamburger. You can call the builder as follows:

class Program
{
	static void Main(string[] args)
	{
		GraphBuilder graphBuilder = new GraphBuilder();
		graphBuilder.CreateGraph();
		ClassyGraph cg = graphBuilder.GetGraph();
		Console.WriteLine(cg);
		Console.ReadKey();
	}
}

Run the app and you’ll see the same output as before. Now we don’t have all the calls to the property setters in Main. It’s encapsulated in a special builder class which takes care of that. We get our specially made graph from the builder. Let’s introduce a bit of creation logic into the builder to represent the steps of building the graph:

private void BuildGraphType()
{
	_classyGraph.GraphType = GraphType.Line;
	_classyGraph.Offset = 1.2;
}

private void ApplyAppearance()
{
	_classyGraph.ColourType = GraphColourPackage.Sad;
	_classyGraph.LargeGraphSize = false;
	_classyGraph.ShowShadow = true;
}

private void ApplySeries()
{
	_classyGraph.PrimarySeries = new List<double>() { 1, 2, 3, 4, 5 };
	_classyGraph.SecondarySeries = new List<double>() { 4, 5, 6, 7, 8 };
}

private void InitialiseGraph()
{
	_classyGraph = new ClassyGraph();
}

We’ll call these methods from CreateGraph:

public void CreateGraph()
{
	InitialiseGraph();
	ApplySeries();
	ApplyAppearance();
	BuildGraphType();	
}

All we’ve done is a bit of refactoring but I think the CreateGraph method reads quite well now with clearly laid-out steps. You can always come back to the individual steps and modify the method bodies, which is analogous to changing a way a lasagne is prepared. You still get a lasagne but the steps the chef – the builder – follows may be different. You as the customer will probably not care. You can also introduce extra validation within each step where the validation result will depend on the previous step.

This is all well and good but we have a new problem now. Let’s add another builder to the app:

public class SpecialGraphBuilder
{

}

It’s kind of empty, right? Well, we’ve just realised that we don’t have a standard way to build a graph. One quick and dirty solution is to copy and paste the code we have in GraphBuilder.cs and modify it. You’ll probably agree however that copy-paste is not a good approach in software engineering. Instead we have to force all types of graphbuilder to follow the same steps, i.e. to standardise the graph building logic. You’ll probably see where we are going: abstraction, correct. So let’s create an abstract class:

public abstract class GraphBuilderBase
{
       private ClassyGraph _classyGraph;

	public ClassyGraph Graph
	{
		get
		{
			return _classyGraph;
		}
	}

	public void InitialiseGraph()
	{
		_classyGraph = new ClassyGraph();
	}

	public abstract void ApplySeries();
	public abstract void ApplyAppearance();
	public abstract void BuildGraphType();	
}

The class initialisation will probably be a common step to all builders so there’s no point in making that abstract. You’ll recognise the abstract methods. Make GraphBuilder inherit from this base class:

public class GraphBuilder : GraphBuilderBase
{
	public void CreateGraph()
	{
		InitialiseGraph();
		ApplySeries();
		ApplyAppearance();
		BuildGraphType();	
	}

	public override void BuildGraphType()
	{
		Graph.GraphType = GraphType.Line;
		Graph.Offset = 1.2;
	}

	public override void ApplyAppearance()
	{
		Graph.ColourType = GraphColourPackage.Sad;
		Graph.LargeGraphSize = false;
		Graph.ShowShadow = true;
	}

	public override void ApplySeries()
	{
		Graph.PrimarySeries = new List<double>() { 1, 2, 3, 4, 5 };
		Graph.SecondarySeries = new List<double>() { 4, 5, 6, 7, 8 };
	}
}

We can then have many different builders that all implement the abstract base. However, you’ll notice that CreateGraph, i.e. the creation logic is still controlled by each implementing class, it is not part of the base. So the client cannot call GraphBuilderBase.CreateGraph. We’ll separate out the creation itself to another class called GraphCreator. The main purpose of this class is to build a graph regardless of what type of graph we’re building:

public class GraphCreator
{
	private GraphBuilderBase _graphBuilder;
	public GraphCreator(GraphBuilderBase graphBuilder)
	{
		_graphBuilder = graphBuilder;
	}

	public void CreateGraph()
	{
		_graphBuilder.InitialiseGraph();
		_graphBuilder.ApplySeries();
		_graphBuilder.ApplyAppearance();
		_graphBuilder.BuildGraphType();	
	}

	public ClassyGraph GetClassyGraph()
	{
		return _graphBuilder.Graph;
	}
}

We inject an abstract graph builder into the constructor and we delegate the creation logic to it. In terms of the pattern the GraphCreator object is called the director. The director uses the builder to build an object. The director won’t care about the exact builder – a concrete builder – type it receives and how the abstract methods are implemented. Its purpose is to hold the creation logic of the ClassyGraph object – called the product – if it’s given a “recipe”, i.e. a builder.

The revised GraphBuilder class looks as follows:

public class GraphBuilder : GraphBuilderBase
{
	public override void BuildGraphType()
	{
		Graph.GraphType = GraphType.Line;
		Graph.Offset = 1.2;
	}

	public override void ApplyAppearance()
	{
		Graph.ColourType = GraphColourPackage.Sad;
		Graph.LargeGraphSize = false;
		Graph.ShowShadow = true;
	}

	public override void ApplySeries()
	{
		Graph.PrimarySeries = new List<double>() { 1, 2, 3, 4, 5 };
		Graph.SecondarySeries = new List<double>() { 4, 5, 6, 7, 8 };
	}
}

This looks very much like an ingredient list, a list of steps with no other “noise”: a data class with zero logic. It is the GraphCreator that controls the creation process. We can now implement the SpecialGraphBuilder class:

public class SpecialGraphBuilder : GraphBuilderBase
{
	public override void ApplySeries()
	{
		Graph.GraphType = GraphType.Bar;
		Graph.Offset = 1.0;
	}

	public override void ApplyAppearance()
	{
		Graph.ColourType = GraphColourPackage.Beautiful;
		Graph.LargeGraphSize = true;
		Graph.ShowShadow = true;
	}

	public override void BuildGraphType()
	{
		Graph.PrimarySeries = new List<double>() { 1, 2, 3, 8, 10 };
		Graph.SecondarySeries = new List<double>() { 4, 5, 9, 3, 4 };
	}
}

We can use this new structure in Main as follows:

static void Main(string[] args)
{
	GraphCreator graphCreator = new GraphCreator(new SpecialGraphBuilder());
	graphCreator.CreateGraph();
	ClassyGraph cg = graphCreator.GetClassyGraph();
	Console.WriteLine(cg);
	Console.ReadKey();
}

It is the GraphCreator that will be responsible to create the graph, we only send in a “recipe” through its constructor. If you instead send in a new GraphBuilder object then the results will be according to that recipe.

Wrap-up

There you are, this is the full implementation of the builder pattern. If you want to create a new type of classy graph then just inherit from the builder base class and inject it into the graph creator constructor.

Note that the pattern is probably an overkill if you only have one concrete builder. The main goal here is to reuse the standardised steps that are generalised in the abstract builder. If you only have one set of data then there is not much value added by applying the pattern. Also, the product that the director is building – and holds an instance of – should be a complex one for the pattern to be useful. The point is that the object is not easy to build: it involves a lot of steps and parameters and validation logic. Creating a product with a single property should not be encapsulated in the builder pattern. In such a case you only increase the complexity of the code instead of reducing it.

Also, bear in mind that the product should always be the same type, i.e. we’re building ClassyGraphs but their internal data is different. Resist the temptation to build a hierarchy of products. The builder is designed to fill in the data and not construct different types of object.

Before I finish up this post: the StringBuilder object in .NET is not an application of the builder pattern. It certainly builds up a string – a product – out of the elements provided in the Append method, but it lacks all the elements of the pattern we talked about in this post: there is no director and there are no multiple implementations of a builder base class or interface.

By the same token fluent APIs are not builders either. Example:

new Graph().Type(GraphType.Line).Colour(Colour.Sad).Offset(1.2) etc.

You’ve probably seen such APIs where you can chain together the methods like that. It looks great and everything but it has the same problem as the StringBuilder class: it lacks the components necessary to constitute the correct implementation of the builder pattern. Also, there’s no enforcing of any kind of creation process.

View the list of posts on Architecture and Patterns here.

Advertisements

Design patterns and practices in .NET: the Facade pattern

Introduction

Even if you’ve just started learning about patterns chances are the you used the Facade pattern before. You just didn’t know that it had a name.

The main intention of the pattern is to hide a large, complex and possibly poorly written body of code behind a purpose-built interface. The poorly written code obviously wasn’t written by you but by those other baaaad programmers you inherited the code from.

The pattern is often used in conjunction with legacy code – if you want to shield the consumers from the complexities of some old-style spaghetti code you will want to hide its methods behind a simplified interface with a couple of methods. In other words you put a facade in front of the complex code. The interface doesn’t necessary cover all the functionality of the complex code, only the parts that are the most interesting and useful for a consumer. Thus the client code doesn’t need to contact the complex code directly, it will communicate with it through the facade interface.

Another typical scenario is when you reference a large external library with hundreds of methods of which you only need a handful. Instead of making the other developers go through the entire library you can extract the most important functions into an interface that all calling code can use. The fact that a lot larger library sits behind the interface is not important to the caller.

It is perfectly fine to create multiple facades to factor out different chunks of functionality from a large API. The facade will also need to be extended and updated if you wish to expose more of the underlying API.

Demo

We’ll simulate an application which looks up the temperature of our current location using several services. We want to show the temperature in Fahrenheit and Celsius as well.

Start Visual Studio and create a new Console application. We start with the simplest service which is the one that converts Fahrenheit to Celsius. Call this class MetricConverterService:

public class MetricConverterService
{
	public double FarenheitToCelcius(double degrees)
	{
		return ((degrees - 32) / 9.0) * 5.0;
	}
}

Next we’ll need a service that looks up our location based on a zip code:

public class GeoLocService
{
	public Coordinates GetCoordinatesForZipCode(string zipCode)
	{
		return new Coordinates()
		{
			Latitude = 10,
			Longitude = 20
		};
	}

	public string GetCityForZipCode(string zipCode)
	{
		return "Seattle";
	}

	public string GetStateForZipCode(string zipCode)
	{
		return "Washington";
	}
}

I don’t actually know the coordinates of Seattle, but building a true geoloc service is way beyond the scope and true purpose of this post.

The Coordinates class is very simple:

public class Coordinates
{
	public double Latitude { get; set; }
	public double Longitude { get; set; }
}

The WeatherService is also very basic:

public class WeatherService
{
	public double GetTempFarenheit(double latitude, double longitude)
	{
		return 86.5;
	}
}

We return the temperature in F based on the coordinates of the location. We of course ignore the true implementation of such a service.

The first implementation of the calling code in the Main method may look as follows:

static void Main(string[] args)
{
	const string zipCode = "SeattleZipCode";

	GeoLocService geoLookupService = new GeoLocService();

	string city = geoLookupService.GetCityForZipCode(zipCode);
	string state = geoLookupService.GetStateForZipCode(zipCode);
	Coordinates coords = geoLookupService.GetCoordinatesForZipCode(zipCode);

	WeatherService weatherService = new WeatherService();
	double farenheit = weatherService.GetTempFarenheit(coords.Latitude, coords.Longitude);

	MetricConverterService metricConverter = new MetricConverterService();
	double celcius = metricConverter.FarenheitToCelcius(farenheit);

	Console.WriteLine("The current temperature is {0}F/{1}C. in {2}, {3}",
		farenheit.ToString("F1"),
		celcius.ToString("F1"),
		city,
        	state);
        Console.ReadKey();
}

The Main method will use the 3 services we created before to perform its work. We first get back some information from the geoloc service based on the zip code. Then we ask the weather service and the metric converter service to get the temperature at that zip code in both F and C.

Run the application and you’ll see some temperature info in the console.

The Main method has to do a lot of things. Getting the zip code in the beginning and writing out the information at the end are trivial tasks, we don’t need to worry about them. However, the method talks to 3 potentially complicated API:s in between. The services may be dlls we downloaded from NuGet or external web services. The Main method will need to know about all three of these services/libraries to carry out its work. It will also need to know how they work, what parameters they need, in what order they must be called etc. Whereas all we really want is to take a ZIP code and get the temperature with the city and state information. It would be beneficial to hide this complexity behind an easy-to-use class or interface.

Let’s insert a new interface:

public interface ITemperatureService
{
	LocalTemperature GetTemperature(string zipCode);
}

…where the LocalTemperature class looks as follows:

public class LocalTemperature
{
	public double Celcius { get; set; }
	public double Farenheit { get; set; }
	public string City { get; set; }
	public string State { get; set; }
}

The interface represents the ideal way to get all information needed by the Main method. LocalTemperature encapsulates the individual bits of information.

Let’s implement the interface as follows:

public class TemperatureService : ITemperatureService
{
	readonly WeatherService _weatherService;
	readonly GeoLocService _geoLocService;
	readonly MetricConverterService _converter;

        public TemperatureService() : this(new WeatherService(), new GeoLocService(), new MetricConverterService())
	{}

	public TemperatureService(WeatherService weatherService, GeoLocService geoLocService, MetricConverterService converter)
	{
		_weatherService = weatherService;
		_converter = converter;
		_geoLocService = geoLocService;
	}

	public LocalTemperature GetTemperature(string zipCode)
	{
		Coordinates coords = _geoLocService.GetCoordinatesForZipCode(zipCode);
		string city = _geoLocService.GetCityForZipCode(zipCode);
		string state = _geoLocService.GetStateForZipCode(zipCode);

		double farenheit = _weatherService.GetTempFarenheit(coords.Latitude, coords.Longitude);
		double celcius = _converter.FarenheitToCelcius(farenheit);

		LocalTemperature localTemperature = new LocalTemperature()
		{
			Farenheit = farenheit,
			Celcius = celcius,
			City = city,
			State = state
		};

		return localTemperature;
	}
}

This is really nothing else than a refactored version of the API calls in the Main method. The dependencies on the external services have been moved to this temperature service implementation. In a more advanced solution those dependencies would be hidden behind interfaces to avoid the tight coupling between them and the Temperature Service and injected via constructor injection. Note that this class structure is not specific to the Facade pattern, so don’t feel obliged to introduce an empty constructor and an overloaded one etc. The goal is to simplify the usage of those external components from the caller’s point of view.

The revised Main method looks as follows:

static void Main(string[] args)
{
	const string zipCode = "SeattleZipCode";

	ITemperatureService temperatureService = new TemperatureService();
	LocalTemperature localTemp = temperatureService.GetTemperature(zipCode);

	Console.WriteLine("The current temperature is {0}F/{1}C. in {2}, {3}",
						localTemp.Farenheit.ToString("F1"),
						localTemp.Celcius.ToString("F1"),
						localTemp.City,
						localTemp.State);

	Console.ReadKey();
}

I think you agree that this is a lot more streamlined solution. So as you see the facade pattern in this case is equal to some sound refactoring of code. Run the application and you’ll see the same output as before we had the facade in place.

Examples from .NET include File I/O operations such as File.ReadAllText(string filename) and the data access types such as Linq to SQL and the Entity Framework. The tedious operations of opening and closing files and database connections are hidden behind simple methods.

View the list of posts on Architecture and Patterns here.

Design patterns and practices in .NET: the Flyweight pattern

Introduction

The main intent of the Flyweight pattern is to structure objects so that they can be shared among multiple contexts. It is often mistaken for factories that are responsible for object creation. The structure of the pattern involves a flyweight factory to create the correct implementation of the flyweight interface but they are certainly not the same patterns.

Object oriented programming is considered a blessing by many .NET and Java programmers and by all others that write code in other object oriented languages. However, it has a couple of challenges. Consider a large object domain where you try to model every component as an object. Example: an Excel document has a large amount of cells. Imagine creating a new Cell object when Excel opens – that would create a large amount of identical objects. Another example is a skyscraper with loads of windows. The windows are potentially identical but there may be some variations to them. As soon as you create a skyscraper object your application may need thousands of window objects as well. If you then create a couple more skyscraper objects your application may eat up all the available memory of your machine.

The flyweight pattern can come to the rescue as it helps reduce the storage cost of a large number of objects. It also allows us to share objects across multiple contexts simultaneously.

The pattern lets us achieve these goals by retaining object oriented granularity and flexibility at the same time.

An anti-pattern solution to the skyscraper-window problem would be to build a superobject that incorporates all window types. You may think that the number of objects may be reduced if you create one type of object instead of 2 or more. However, why should that number decrease??? You still have to new up the window objects, right? In addition, such superobjects can quickly become difficult to maintain as you need to accommodate several different types of objects within it and you’ll end up with lots of if statements, possibly nested ones.

The ideal solution in this situation is to create shared objects. Why build 1000 window objects if 1 suffices or at least as few as possible?

The key to creating shared objects is to distinguish between the intrinsic and extrinsic state of an object. The shared objects in the pattern are called Flyweights.

Extrinsic state is supplied to the flyweight from the outside as a parameter when some operation is called on it. This state is not stored inside the flyweight. Example: a Window object may have a Draw operation where the object draws itself. The initial implementation of the Window object may have X and Y co-ordinates plus Width and Height. Those states are contextual can be externalised as parameters to the Draw method: Draw(int x, int y, int width, int height).

Intrinsic state on the other hand is stored inside the flyweight. It does not depend on the context hence it is shareable. The Window object may have a Brush object that is used to draw it. The Brush used to draw the window is the same irrespective of the co-ordinates and size of the window. Thus a single brush can be shared across window objects to draw the windows of the same size.

We still need to make sure that the clients do not end up creating their own flyweights. Even if we implement the extrinsic and intrinsic states everyone is free to create their own copies of the object, right? The answer to that challenge is to use a Flyweight factory. This factory creates and manages flyweights. The client will communicate with the factory if it needs a flyweight. The factory will either provide an existing one or create a new one depending on inputs coming from the client. The client doesn’t care which.

Also, we can have distinct Window objects that are somehow unique among all window objects. There may only be a handful of those on a skyscraper. These may not be shared and they store all their state. These objects are unshared flyweights.

Note however that if the objects must be identified by an ID then this pattern will not be applicable. In other words if you need to distinguish between the second window from the right on the third floor and the sixth window from the left on the fifth floor then you cannot possibly share the objects. In Domain Driven Design such id-less objects are called Value Objects as opposed to Entities that have a unique ID. Value Objects have no ID so it doesn’t make any difference which specific window object you put in which position. If you have such objects in your domain model then they are a good candidate for flyweights.

Demo

In the demo we’ll demonstrate sharing Window objects. Fire up Visual Studio and create a new blank solution. Insert a class library called Domain. Every Window will need to implement the IWindow interface:

public interface IWindow
{
	void Draw(Graphics g, int x, int y, int width, int height);
}

You’ll need to add a reference to the System.Drawing library. Note that we pass in parameters that you may first introduce as object properties: x, y, width, height. These are the parameters that represent the extrinsic state mentioned before. They are computed and supplied by the consumer of the object. They can even be stored in a database table if the Window objects have pre-set sizes which is very likely.

We have the following concrete window types:

public class RedWindow : IWindow
	{
		public static int ObjectCounter = 0;
		Brush paintBrush;

		public RedWindow()
		{
			paintBrush = Brushes.Red;
			ObjectCounter++;
		}

		public void Draw(Graphics g, int x, int y, int width, int height)
		{
			g.FillRectangle(paintBrush, x, y, width, height);
		}
	}
public class BlueWindow : IWindow
	{
		public static int ObjectCounter = 0;

		Brush paintBrush;

		public BlueWindow()
		{
			paintBrush = Brushes.Blue;
			ObjectCounter++;
		}

		public void Draw(Graphics g, int x, int y, int width, int height)
		{
			g.FillRectangle(paintBrush, x, y, width, height);
		}
	}

You’ll see that we have a static object counter. This will help us verify how many objects were really created by the client. The Brush object represents an intrinsic state as mentioned above. It is stored within the object.

The Window objects are built by the WindowFactory:

public class WindowFactory
	{
		static Dictionary<string, IWindow> windows = new Dictionary<string, IWindow>();

		public static IWindow GetWindow(string windowType)
		{
			switch (windowType)
			{
				case "Red":
					if (!windows.ContainsKey("Red"))
						windows["Red"] = new RedWindow();
					return windows["Red"];
				case "Blue":
					if (!windows.ContainsKey("Blue"))
						windows["Blue"] = new BlueWindow();
					return windows["Blue"];
				default:
					break;
			}
			return null;
		}
	}

The client will contact the factory to get hold of a Window object. It will send in a string parameter which describes the type of the window. You’ll note that the factory has a dictionary where it stores the available Window types. This is a tool for the factory to manage the pool of shared tiles. Look at the switch statement: the factory checks if the requested window type is already available in the dictionary using the window type description as the key. If not then it creates a new concrete window and adds it to the dictionary. Finally it returns the correct window object. Note that the factory only creates a new window the first time it is contacted. It returns the existing object on all subsequent requests.

How would a client use this code? Add a new Windows Forms Application called SkyScraper to the solution. Rename Form1 to WindowDemo. Put a label control on the form and name it lblObjectCounter. Put it as far to one of the edges of the form as possible.

We’ll use a random number generator to generate the size parameters of the window objects. We will paint 40 windows on the form: 20 red and 20 blue ones. The total number of objects created should however be 2: one blue and one red. The WindowDemo code behind looks as follows:

public partial class WindowDemo : Form
	{
		Random random = new Random();

		public WindowDemo()
		{
			InitializeComponent();
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			base.OnPaint(e);

			for (int i = 0; i < 20; i++)
			{
				IWindow redWindow = WindowFactory.GetWindow("Red");
				redWindow.Draw(e.Graphics, GetRandomNumber(),
					GetRandomNumber(), GetRandomNumber(), GetRandomNumber());
			}

			for (int i = 0; i < 20; i++)
			{
				IWindow stoneTile = WindowFactory.GetWindow("Blue");
				stoneTile.Draw(e.Graphics, GetRandomNumber(),
					GetRandomNumber(), GetRandomNumber(), GetRandomNumber());
			}

			this.lblObjectCounter.Text = "Total Objects Created : " +
				Convert.ToString(RedWindow.ObjectCounter
				+ BlueWindow.ObjectCounter);
		}

		private int GetRandomNumber()
		{
			return (int)(random.Next(100));
		}       
	}

You’ll need to add a reference to the Domain project.

We’ll paint the Window objects in the overridden OnPaint method. Otherwise the code should be pretty easy to follow. Compile and run the application. You should see red and blue squares painted on the form. The object counter label should say 2 verifying that our flyweight implementation was correct.

Before I close this post try the following bit of code:

string s1 = "flyweight";
string s2 = "flyweight";
bool areEqual = ReferenceEquals(s1, s2);

Can you guess what value areEqual will have? You may think it’s false as s1 and s2 are two different objects and strings are reference types. However, .NET maintains a string pool to manage space and replaces the individual strings to a shared instance.

View the list of posts on Architecture and Patterns here.

Design patterns and practices in .NET: the Mediator pattern

Introduction

The Mediator pattern can be applicable when several objects of a related type need to communicate with each other and this communication is complex. Consider a scenario where incoming aircraft need to carefully communicate with each other for safety reasons. They constantly need to know the position of all other planes, meaning that each aircraft needs to communicate with all other aircraft.

Think of a first naive solution in this case. You have 3 types of aircraft in your domain model: Boeing, Airbus and Fokker. Consider that each type needs to communicate with the other two types. The first approach would be to check the type of the other aircraft directly in code such as this in the Airbus class:

if (otherAircraft is Boeing)
{
    //do something
}
else if (otherAircraft is Fokker)
{
    //do something else
}

You would have similar if-else statements in the other two classes. You can imagine how this gets out of control as we add new types of aircraft. You’ll need to revisit the code of all other types and extend the if-else statements to accommodate the new type thereby violating the open-close design principle. Also, it’s bad practice to let one class intimately know about the inner workings of another class, which is the case here.

We need to decouple the related objects from each other. This is where a Mediator enters the scene. A mediator encapsulates the interaction logic among related objects. The pattern allows loose coupling between objects by keeping them from directly referring to each other explicitly. The interaction logic is centralised in one place only.

The above problem has been solved through air traffic controllers in the real world. It is those professionals that will monitor the position of each aircraft in their zone and communicate with them directly. I don’t know if pilots of different commercial planes directly contact each other but I can imagine that it occurs very rarely. If we applied the same solution in this case then the pilots would need to know if every type of aircraft they may encounter during their flight.

There are a couple of formal elements to the Mediator pattern:

  • Colleagues: components that need to communicate with each other, very often of the same base type. These objects will have no knowledge of each other but will know about the Mediator component
  • Mediator: a centralised component that manages communication between the colleagues. The colleagues will have a dependency on this object through an abstraction

Demo

We’ll build on the idea mentioned above: the colleague elements are the incoming aircraft and the mediator is represented by an air traffic controller.

Start up Visual Studio and create a new Console application. Insert a base class for all colleagues called Aircraft:

public abstract class Aircraft
	{
		private readonly IAirTrafficControl _atc;
		private int _currentAltitude;

		protected Aircraft(string callSign, IAirTrafficControl atc)
		{
			_atc = atc;
			CallSign = callSign;
			_atc.RegisterAircraftUnderGuidance(this);
		}

		public abstract int Ceiling { get; }

		public string CallSign { get; private set; }

		public int Altitude
		{
			get { return _currentAltitude; }
			set
			{
				_currentAltitude = value;
				_atc.ReceiveAircraftLocation(this);
			}
		}

		public void Climb(int heightToClimb)
		{
			Altitude += heightToClimb;
		}

		public override bool Equals(object obj)
		{
			if (obj.GetType() != this.GetType()) return false;

			var incoming = (Aircraft)obj;
			return this.CallSign.Equals(incoming.CallSign);
		}

		public override int GetHashCode()
		{
			return CallSign.GetHashCode();
		}

		public void WarnOfAirspaceIntrusionBy(Aircraft reportingAircraft)
		{
			//do something in response to the warning
		}
	}

Every aircraft will have a call sign and a dependency on an air flight controller in the form of the IAirTrafficController interface. We’ll take a look at that interface shortly but you’ll see that we put the aircraft under the responsibility of that air traffic control. We tell the mediator that there’s a new object that it needs to communicate with.

You can imagine that as commercial aircraft fly to their destinations they enter and leave the zones of various air traffic controls on their way. So in a more complete interface would have a de-register method as well but we can omit that to keep the demo simple.

Then comes an abstract property called Ceiling that shows the maximum flying altitude of the aircraft. Each concrete type will need to communicate this property about itself. This is followed by the current Altitude of the aircraft. You’ll see that in the property setter we send the current location to the air traffic controller.

The rest of the class is pretty simple: we let the aircraft climb, we make them comparable and we let them receive a warning signal if there is another aircraft too close.

The IAirTrafficControl interface looks as follows:

public interface IAirTrafficControl
	{
		void ReceiveAircraftLocation(Aircraft location);
		void RegisterAircraftUnderGuidance(Aircraft aircraft);
	}

The type that implements the IAirTrafficControl interface will be responsible to implement these methods. The Aircraft object doesn’t care how its position is registered at the control.

We have the following concrete types of aircraft:

public class Boeing : Aircraft
	{
		public Boeing(string callSign, IAirTrafficControl atc)
			: base(callSign, atc)
		{
		}

		public override int Ceiling
		{
			get { return 33000; }
		}
	}
public class Fokker : Aircraft
	{
		public Fokker(string callSign, IAirTrafficControl atc) : base(callSign, atc)
        {
        }

		public override int Ceiling
		{
			get { return 40000; }
		}
	}
public class Airbus : Aircraft
	{
		public Airbus(string callSign, IAirTrafficControl atc)
			: base(callSign, atc)
		{
		}

		public override int Ceiling
		{
			get { return 40000; }
		}
	}

These should be fairly easy to follow. If you later want to introduce a new type of aircraft just derive from the Aircraft base class and then it will automatically become a colleague component to the existing types. The important thing to note is that in any concrete type there is no reference to any other type. The colleagues are completely independent. That dependency is replaced by the IAirTrafficControl abstraction which is the definition of the mediator. You can imagine that we can pass in different types of air traffic control as the plane flies towards its destination: Stockholm, Copenhagen, Hamburg etc. They may all treat the aircraft in their zones little differently.

Let’s take a look at the concrete mediator:

public class Tower : IAirTrafficControl
	{
		private readonly IList<Aircraft> _aircraftUnderGuidance = new List<Aircraft>();

		public void ReceiveAircraftLocation(Aircraft reportingAircraft)
		{
			foreach (Aircraft currentAircraftUnderGuidance in _aircraftUnderGuidance.
				Where(x => x != reportingAircraft))
			{
				if (Math.Abs(currentAircraftUnderGuidance.Altitude - reportingAircraft.Altitude) < 1000)
				{
					reportingAircraft.Climb(1000);
					//communicate to the class
					currentAircraftUnderGuidance.WarnOfAirspaceIntrusionBy(reportingAircraft);
				}
			}
		}

		public void RegisterAircraftUnderGuidance(Aircraft aircraft)
		{
			if (!_aircraftUnderGuidance.Contains(aircraft))
			{
				_aircraftUnderGuidance.Add(aircraft);
			}
		}
	}

The Tower maintains a list of Aircraft that belong under its control. The list is augmented using the implemented RegisterAircraftUnderGuidance method.

The ReceiveAircraftLocation method includes a bit of logic. When an aircraft reports its position then the Tower loops through the list of aircraft currently under its control – except for the one reporting its position – and if any other plane is within 1000 feet then the reporting aircraft needs to climb 1000 feet and the current aircraft in the loop is warned of another aircraft flying too close. This emergency call is a form of indirect communication between two colleagues: the reporting aircraft communicates tells the other aircraft of the violation of the flying distance. The communication is mediated using the Tower class, the two concrete aircraft still have no knowledge about each other, all communication is handled through abstractions.

Let’s look at the Main method:

static void Main(string[] args)
{
	IAirTrafficControl tower = new Tower();

	Aircraft flight1 = new Airbus("AC159", tower);
	Aircraft flight2 = new Boeing("WS203", tower);
	Aircraft flight3 = new Fokker("AC602", tower);

	flight1.Altitude += 1000;
}

We create a mediator and the aircraft currently flying. That’s all we need to introduce a new aircraft: tell it about the mediator it can use for its communication purposes through its constructor.

The last row says that the Airbus will increase its altitude by 1000 feet. If you recall then the Altitude property setter will initiate a communication with the air traffic control. The aircraft indicates its new altitude and the Tower will loop through the list of aircraft currently under its control and see of any other aircraft object is too close to the reporting one.

The main advantage of the mediator pattern is abstraction: we hide the communicating colleagues from each other and let them talk to each other through another abstraction, i.e. the mediator. An aircraft can only belong to a single mediator and a mediator can have many colleagues under its control, i.e. this is a one-to-many relationship. If we remove the mediator then we’re immediately dealing with a many-to-many relationship among colleagues. If you’re like me then you probably prefer the former type of relationship to the latter.

The disadvantage of the mediator lies in its possible complexity. Our example is still very simple but in real life examples the communication can become very messy with if statements checking the type of the colleague. The mediator can grow very large as more and more communication logic enters the picture. The problem can be mitigated by breaking down the mediator to smaller chunks adhering to the single responsibility principle.

View the list of posts on Architecture and Patterns here.

Design patterns and practices in .NET: the Interpreter pattern

Introduction

The Interpreter pattern is somewhat different from the other design patterns. It’s easily overlooked and many find it difficult to understand and apply. Formally the pattern is about handling languages based on a set of rules. So we have a language – any language – and its rules, i.e. the grammar. We also have an interpreter that takes the set of rules to interpret the sentences of the language. You will probably not use this pattern in your everyday programming work – except maybe if you work with robots that need to read some formal representation of an object.

Barcodes are real life examples of the pattern. Barcodes are usually not readable by humans because we don’t know the rules of the barcode language. However, we can take an interpreter, i.e. a barcode reader which will use the barcode rules stored within it to tell us what kind of product we have just bought. The language is represented by the bars of the barcode. The grammar is represented by the numerical values of the bars.

What does all that have to do with programming??? We’ll try to find out.

Demo

Open Visual Studio and create a new Console application. In our demo we’ll simulate a sandwich builder. We’ll create a sandwich language and we want to print the instructions for building the sandwich.

We want to represent a sandwich as follows. We have the top bread and the bottom bread with as many ingredients in between as you like. The ingredients can be condiments such as ketchup or mayo and other ingredients such as ham or vegetables. An additional rule is that the ingredients cannot be applied in any order. We first have one or more condiments, then some ‘normal’ ingredients such as chicken, followed by some more condiments.

We will have the following spices: mayo, mustard and ketchup. Ingredients include lettuce, tomato and chicken. Bread can be either white bread or wheat bread. The ingredients are grouped into a condiment list and an ingredient list. Each list can contain 0 or more elements. In an extreme case we can have a very plain sandwich with only the top and bottom bread.

The goal is to give instructions to a machine which will build sandwiches for us. We won’t go overboard with our notations so that the result can be understood by a human, but you can replace the ingredients and bread types with any symbol you like.

The ingredients of our sandwich – bread, condiment, etc. – and the sandwich itself are the sentences or expressions in our sandwich language. This will be the first element in our programme, the IExpression interface:

public interface IExpression
	{
		void Interpret(Context context);
	}

Each expression has a meaning so it can be interpreted, hence the Interpret method. The sandwich means something. The list of condiments and ingredients mean something, they are all expressions. In order to understand the meaning of a sandwich we need to know the meaning of each ingredient and condiment. The Context class represents the context within which the Expression is interpreted. In this case it’s a very simple class:

public class Context
	{
		public string Output { get; set; }
	}

We only use the context for our output.

Each condiment implements the ICondiment interface which is extremely simple:

public interface ICondiment : IExpression { }

Each ingredient implements the IIngredient interface which again is very simple:

public interface IIngredient : IExpression{}

Here come the condiment types, they should be easy to follow. The Interpret method appends the name of the condiment to the string output in each case. This is possible as a single condiment doesn’t have any children so it can interpret itself:

public class KetchupCondiment : ICondiment
	{
		public void Interpret(Context context)
		{
			context.Output += string.Format(" {0} ", "Ketchup");
		}
	}
public class MayoCondiment : ICondiment
	{
		public void Interpret(Context context)
		{
			context.Output += string.Format(" {0} ", "Mayo");
		}
	}
public class MustardCondiment : ICondiment
	{
		public void Interpret(Context context)
		{
			context.Output += string.Format(" {0} ", "Mustard");
		}
	}

The condiments are grouped in a Condiment list:

public class CondimentList : IExpression
	{
		private readonly List<ICondiment> condiments;

		public CondimentList(List<ICondiment> condiments)
		{
			this.condiments = condiments;
		}

		public void Interpret(Context context)
		{
			foreach (ICondiment condiment in condiments)
				condiment.Interpret(context);
		}
	}

The Interpret method simply iterates through the members of the Condiment list and calls the interpret method on each.

Here come the ingredients which implement the Interpret method the same way:

public class LettuceIngredient : IIngredient
	{
		public void Interpret(Context context)
		{
			context.Output += string.Format(" {0} ", "Lettuce");
		}
	}
public class ChickenIngredient : IIngredient
	{
		public void Interpret(Context context)
		{
			context.Output += string.Format(" {0} ", "Chicken");
		}
	}

The ingredients are also grouped into an ingredient list:

public class IngredientList : IExpression
	{
		private readonly List<IIngredient> ingredients;

		public IngredientList(List<IIngredient> ingredients)
		{
			this.ingredients = ingredients;
		}

		public void Interpret(Context context)
		{
			foreach (IIngredient ingredient in ingredients)
				ingredient.Interpret(context);
		}
	}

Now all we need is to represent the bread somehow:

public interface IBread : IExpression{}

Here come the bread types:

public class WheatBread : IBread
	{
		public void Interpret(Context context)
		{
			context.Output += string.Format(" {0} ", "Wheat-Bread");
		}
	}
public class WhiteBread : IBread
	{
		public void Interpret(Context context)
		{
			context.Output += string.Format(" {0} ", "White-Bread");
		}
	}

Now we have all the elements ready to build our Sandwich class:

public class Sandwhich : IExpression
	{
		private readonly IBread topBread;
		private readonly CondimentList topCondiments;
		private readonly IngredientList ingredients;
		private readonly CondimentList bottomCondiments;
		private readonly IBread bottomBread;

		public Sandwhich(IBread topBread, CondimentList topCondiments, IngredientList ingredients, CondimentList bottomCondiments, IBread bottomBread)
		{
			this.topBread = topBread;
			this.topCondiments = topCondiments;
			this.ingredients = ingredients;
			this.bottomCondiments = bottomCondiments;
			this.bottomBread = bottomBread;
		}

		public void Interpret(Context context)
		{
			context.Output += "|";
			topBread.Interpret(context);
			context.Output += "|";
			context.Output += "<--";
			topCondiments.Interpret(context);
			context.Output += "-";
			ingredients.Interpret(context);
			context.Output += "-";
			bottomCondiments.Interpret(context);
			context.Output += "-->";
			context.Output += "|";
			bottomBread.Interpret(context);
			context.Output += "|";
			Console.WriteLine(context.Output);
		}
	}

We build the sandwich using the 5 objects in the constructor: the top bread, top condiments, ingredients in the middle, bottom condiments and finally the bottom bread. The Interpret method builds our sandwich machine language:

  • We start with a delimiter ‘|’
  • Followed by the top bread interpretation
  • Then comes the bread delimiter again ‘|’
  • “<–"; indicates the start of the things in the sandwich
  • Then come the top condiments interpretation
  • Followed by a ‘-‘ delimiter
  • Ingredients
  • Againt followed by the ‘-‘ delimiter
  • Bottom condiments
  • The sandwich filling is then closed with “–>”
  • The bottom bread is surrounded by pipe characters like the top bread

Note that every element in the sandwich, including the sandwich itself, can interpret itself. This is of course due to the fact that every element here is an expression, a sentence that has a meaning and can be interpreted.

The Interpret method in each implementation builds up the grammar of our sandwich language. The ultimate Interpret method in the Sandwich class builds up the sentences in sandwich language according to the rules of that grammar. We let each expression interpret itself – it is a lot easier to let each element do it instead of going through some complicated string operation and if-else statements trying build up our sentences. Not just that – we built our object model with our domain knowledge in mind so the solution is a lot more object oriented and reflects our business logic.

Let’s see how this can be used by a client. Let’s insert the following in the Main method:

class Program
	{
		static void Main(string[] args)
		{
			Sandwhich sandwhich = new Sandwhich(
				new WheatBread(),
				new CondimentList(
					new List<ICondiment> { new MayoCondiment(), new MustardCondiment() }),
				new IngredientList(
					new List<IIngredient> { new LettuceIngredient(), new ChickenIngredient() }),
				new CondimentList(new List<ICondiment> { new KetchupCondiment() }),
				new WheatBread());

			sandwhich.Interpret(new Context());


			Console.ReadKey();
		}
	}

We build a sandwich using the Sandwich constructor where we pass in each element of the sandwich. As the sandwich itself is also an expression we can call its interpret method to output the representation of the sandwich.

Run the application and you’ll see our beautiful instructions to build a sandwich. Feel free to change the ingredients and check the output in the console.

View the list of posts on Architecture and Patterns here.

Design patterns and practices in .NET: the Composite pattern

Introduction

The Composite pattern deals with putting individual objects together to form a whole. In mathematics the relationship between the objects and the composite object they build can be described by a part-whole hierarchy. The ingredient objects are the parts and the composite is the whole.

In essence we build up a tree – a composite – that consists of one or more children – the leaves. The client calling upon the composite should be able to treat the individual parts of the whole in a uniform way.

A real life example is sending emails. If you want to send an email to all developers in your organisation one option is that you type in the names of each developer in the ‘to’ field. This is of course not efficient. Fortunately we can construct recipient groups, such as Developers. If you then also want to send the email to another person outside the Developers group you can simply put their name in the ‘to’ box along with Developers. We treat both the group and the individual emails in a uniform way. We can insert both groups and individual emails in the ‘to’ box. We rely on the email engine to take the group apart and send the email to each recipient in that group. We don’t really care how it’s done – apart from a couple network geeks I guess.

Demo

We will first build a demo application that does not use the pattern and then we’ll refactor it. We’ll simulate a game where play money is split among the players in a group if they manage to kill a monster.

Start up Visual Studio and create a new console application. Insert a new class called Player:

public class Player
	{
		public string Name { get; set; }
		public int Gold { get; set; }

		public void Stats()
		{
			Console.WriteLine("{0} has {1} coins.", Name, Gold);
		}
	}

This is easy to follow I believe. A group of players is represented by the Group class:

public class Group
	{
		public string Name { get; set; }
		public List<Player> Members { get; set; }

		public Group()
		{
			Members = new List<Player>();
		}
	}

The money splitting mechanism is run in the Main method as follows:

static void Main(string[] args)
{
	int goldForKill = 1023;
	Console.WriteLine("You have killed the Monster and gained {0} coins!", goldForKill);

	Player andy = new Player { Name = "Andy" };
	Player jane = new Player { Name = "Jane" };
	Player eve = new Player { Name = "Eve" };
	Player ann = new Player { Name = "Ann" };
	Player edith = new Player { Name = "Edith" };
	Group developers = new Group { Name = "Developers", Members = { andy, jane, eve } };

	List<Player> individuals = new List<Player> { ann, edith };
	List<Group> groups = new List<Group> { developers };

	double totalToSplitBy = individuals.Count + groups.Count;
	double amountForEach = goldForKill / totalToSplitBy;
	int leftOver = goldForKill % totalToSplitBy;

	foreach (Player individual in individuals)
	{
		individual.Gold += amountForEach + leftOver;
		leftOver = 0;
		individual.Stats();
	}

	foreach (Group group in groups)
	{
		double amountForEachGroupMember = amountForEach / group.Members.Count;
		int leftOverForGroup = amountForEachGroupMember % group.Members.Count;
		foreach (Player member in group.Members)
		{
			member.Gold += amountForEachGroupMember + leftOverForGroup;
			leftOverForGroup = 0;
			member.Stats();
		}
	}

	Console.ReadKey();
}

So our brilliant game starts off where the monster was killed and we’re ready to hand out the reward among the players. We have 5 players. Three of them make up a group and the other two make up a list of individual players. We’re then ready to split the gold among the participants where the group is counted as one unit i.e. we have 3 elements: the two individual players and the Developer group. Then we go through each individual and give them their share. We do the same to each group as well where we also divide the group’s share among the individuals within that group.

Build and run the application and you’ll see in the console that the 1023 pieces of gold was divided up. The code works but it’s definitely quite messy. Keep in mind that our tree hierarchy is very simple: we can have individuals and groups. Think of a more complicated scenario: within the Developers group we can have subgroups, such as .NET developers, Java developers who are further subdivided into web and desktop developers and even individuals that do not fit into any group. In the code we iterate through the individuals and the groups manually. We also iterate the players in the group. Imagine that we’d have to iterate through the subgroups of the subgroups of the group if we are facing a deeper hierarchy. The foreach loop would keep growing and the splitting logic would become very challenging to maintain.

So let’s refactor the code. The composite pattern states that the client should be able to treat the individual part and the whole in a uniform way. Thus the first step is to make the Person and the Group class uniform in some way. As it turns out the logical way to do this is that both classes implement an interface that the client can communicate with. So the client won’t deal with groups and individuals but with a uniform object, such as Participant.

Insert an interface called IParticipant:

public interface IParticipant
{
	int Gold { get; set; }
	void Stats();
}

Every participant of the game will have some gold and will be able to write out the current statistics regardless of them being individuals or groups. We let Player and Group implement the interface:

public class Player : IParticipant
	{
		public string Name { get; set; }
		public int Gold { get; set; }

		public void Stats()
		{
			Console.WriteLine("{0} has {1} coins.", Name, Gold);
		}
	}

The Player class implements the interface without changes in its body.

The Group class will encapsulate the gold sharing logic we saw in the Main method above:

public class Group : IParticipant
	{
		public string Name { get; set; }
		public List<IParticipant> Members { get; set; }

		public Group()
		{
			Members = new List<IParticipant>();
		}

		public int Gold
		{
			get
			{
				int totalGold = 0;
				foreach (IParticipant member in Members)
				{
					totalGold += member.Gold;
				}

				return totalGold;
			}
			set
			{
				double eachSplit = value / Members.Count;
				int leftOver = value % Members.Count;
				foreach (IParticipant member in Members)
				{
					member.Gold += eachSplit + leftOver;
					leftOver = 0;
				}
			}
		}

		public void Stats()
		{
			foreach (IParticipant member in Members)
			{
				member.Stats();
			}
		}
	}

In the Gold property getter we simply loop through the group members and add up their amount of gold. In the setter we split up the total amount of gold among the group members. Note also that Group can have a list of IParticipant objects representing either individual players or subgroups. You can imagine that those subgroups in turn can also have subgroups so the setters and getters will automatically collect the information from the nested members as well. The leftover variable is set to 0 as the first member will be given all the left over, we don’t care about such details.

In the Stats method we simply call the statistics of each group member – again group members can be individuals and subgroups. If it’s a subgroup then the Stats method of the members of the subgroup will automatically be called.

The modified Main method looks as follows:

static void Main(string[] args)
{
	int goldForKill = 1023;
	Console.WriteLine("You have killed the Monster and gained {0} coins!", goldForKill);

	IParticipant andy = new Player { Name = "Andy" };
	IParticipant jane = new Player { Name = "Jane" };
	IParticipant eve = new Player { Name = "Eve" };
	IParticipant ann = new Player { Name = "Ann" };
	IParticipant edith = new Player { Name = "Edith" };
	IParticipant oldBob = new Player { Name = "Old Bob" };
	IParticipant newBob = new Player { Name = "New Bob" };
	IParticipant bobs = new Group { Members = { oldBob, newBob } };
	IParticipant developers = new Group { Name = "Developers", Members = { andy, jane, eve, bobs } };

	IParticipant participants = new Group { Members = { developers, ann, edith } };
	participants.Gold += goldForKill;
	participants.Stats();

	Console.ReadKey();
}

You can see that the client, i.e. the Main method calls the methods of IParticipant where IParticipant can be an individual, a group or a group within a group. When we set the level gold through the Gold property the gold distribution logic of each concrete type is called which even takes care of sharing the gold among the groups within a group. The participants variable includes all members of the game.

The main advantage of this pattern is that now the tree structure can be as deep as you can imagine and you don’t have to change the logic within the Player and Group classes. Also, we contain the differences between a leaf and a group in the Player and Group classes separately. In addition, they can also tested independently.

Build and run the project and you should see the amount of gold split among all participants of the game.

View the list of posts on Architecture and Patterns here.

Design patterns and practices in .NET: the Chain of Responsibility pattern

Introduction

The Chain of Responsibility is an ordered chain of message handlers that can process a specific type of message or pass the message to the next handler in the chain. This pattern revolves around messaging between a sender and one more receivers. This probably sounds very cryptic – just like the basic description of design patterns in general – so let’s see a quick example in words.

Suppose we have a Sender that knows the first receiver in the messaging chain, call it Receiver A. Receiver A is in turn aware of Receiver B and so on. When a message comes in to a sender we can only perform one thing: pass it along to the first receiver. Receiver A inspects the message and decides whether it can process it or not. If not then it passes the message along to Receiver B and Receiver B will perform the same message inspection as Receiver A. It then decides to either process the Message or send it further down the messaging chain. If it processes the message then it will send a Response back to the Sender.

In this example the Sender sent a message to the first Receiver and received a Response from a different one. However, the Sender is not aware of Receiver B. If the messaging stops at Receiver B then Receiver C remained completely inactive: it has no knowledge of the Message and that the messaging actually occurred.

The example also showcases the traits of the pattern:

  • The Sender is only aware of the first receiver
  • Each receiver only knows of the next receiver down the messaging chain
  • Receivers can process the Message or send it down the chain
  • The Sender will have no knowledge about which Receiver received the message
  • The first receiver that was able to process the message terminates the chain
  • The order of the receiver list matters

Demo

In the demo we’ll simulate the hierarchy of a company: an employee would like to make a large expenditure so he asks his manager. The manager is not entitled to approve the large sum and sends the request forward to the VP. The VP is not entitled either to approve the request so sends it to the President. The President is the highest authority in the hierarchy who will either approve or disapprove the request and sends the response back to the original employee.

Open Visual Studio and create a blank solution. Insert a class library called Domain. You can remove Class1.cs. We’ll build up the components one by one. We’ll start with the abstraction for an expense report, IExpenseReport:

public interface IExpenseReport
    {
        Decimal Total { get; }
    }

An expense report can thus have a total sum.

The IExpenseApprover interface represents any object that is entitled to approve expense reports:

public interface IExpenseApprover
	{
		ApprovalResponse ApproveExpense(IExpenseReport expenseReport);
	}

…where ApprovalResponse is an enumeration:

public enum ApprovalResponse
	{
		Denied,
		Approved,
		BeyondApprovalLimit,
	}

The concrete implementation of the IExpenseReport is very straightforward:

public class ExpenseReport : IExpenseReport
	{
		public ExpenseReport(Decimal total)
		{
			Total = total;
		}

		public decimal Total
		{
			get;
			private set;
		}
	}

The Employee class implements the IExpenseApprover interface:

public class Employee : IExpenseApprover
	{
		public Employee(string name, Decimal approvalLimit)
		{
			Name = name;
			_approvalLimit = approvalLimit;
		}

		public string Name { get; private set; }

		public ApprovalResponse ApproveExpense(IExpenseReport expenseReport)
		{
			return expenseReport.Total > _approvalLimit
					? ApprovalResponse.BeyondApprovalLimit
					: ApprovalResponse.Approved;
		}

		private readonly Decimal _approvalLimit;
	}

As you see the constructor needs a name and an approval limit. The implemented ApproveExpense method simply checks if the total value of the expense report is above or below the approval limit. If total is lower than the limit, then the expense is approved, otherwise the method indicates that the total is too much for the employee to approve.

Add a Console application called Approval to the solution and add a reference to the Domain library. We’ll first check how the approval process may look like without the pattern applied:

static void Main(string[] args)
		{
			List<Employee> managers = new List<Employee>
                                          {
                                              new Employee("William Worker", Decimal.Zero),
                                              new Employee("Mary Manager", new Decimal(1000)),
                                              new Employee("Victor Vicepres", new Decimal(5000)),
                                              new Employee("Paula President", new Decimal(20000)),
                                          };

			Decimal expenseReportAmount;
			while (ConsoleInput.TryReadDecimal("Expense report amount:", out expenseReportAmount))
			{
				IExpenseReport expense = new ExpenseReport(expenseReportAmount);

				bool expenseProcessed = false;

				foreach (Employee approver in managers)
				{
					ApprovalResponse response = approver.ApproveExpense(expense);

					if (response != ApprovalResponse.BeyondApprovalLimit)
					{
						Console.WriteLine("The request was {0}.", response);
						expenseProcessed = true;
						break;
					}
				}

				if (!expenseProcessed)
				{
					Console.WriteLine("No one was able to approve your expense.");
				}
			}
		}

…where ConsoleInput is a helper class that looks as follows:

public static class ConsoleInput
	{
		public static bool TryReadDecimal(string prompt, out Decimal value)
		{
			value = default(Decimal);

			while (true)
			{
				Console.WriteLine(prompt);
				string input = Console.ReadLine();

				if (string.IsNullOrEmpty(input))
				{
					return false;
				}

				try
				{
					value = Convert.ToDecimal(input);
					return true;
				}
				catch (FormatException)
				{
					Console.WriteLine("The input is not a valid decimal.");
				}
				catch (OverflowException)
				{
					Console.WriteLine("The input is not a valid decimal.");
				}
			}
		}
	}

What can we say about the Main method? We first set up our employees with the approval limits in increasing order. The next step is to read an expense report from the command line. Using that sum we construct an expense report which is given to every employee in the list. Each employee is asked to approve the limit and we check the outcome. If the expense is approved then we break the foreach loop.

Build and run the application. Enter 5000 in the console and you’ll see that the expense was approved. You’ll recall that the VP had an approval limit of 5000 so it was that employee in the chain to approve. Enter 50000 and you’ll see that nobody was able to approve the expense because it exceeds the limit of every one of them.

What is wrong with this implementation? After all we iterate through the employee list to see if anyone is able to approve the expense. We get our response and we get to know the outcome.

The problem is that the caller is responsible for iterating through the list. This means that the logic of handling expense reports is encapsulated at the wrong level. Imagine that you as an employee should not ask each one of the managers above you for a yes or no answer. You should only have to turn to your boss who in turn will ask his or her boss etc. Our code should reflect this.

In order to achieve that we need to insert a new interface:

public interface IExpenseHandler
	{
		ApprovalResponse Approve(IExpenseReport expenseReport);
		void RegisterNext(IExpenseHandler next);
	}

The Approve method should look familiar from the previous descriptions. The RegisterNext method registers the next approver in the chain. It means that if I cannot approve the expense then I should go and ask the next person in line.

This interface represents a single link in the chain of responsibility.

The IExpenseHandler interface is implemented by the ExpenseHandler class:

public class ExpenseHandler : IExpenseHandler
	{
		private readonly IExpenseApprover _approver;
		private IExpenseHandler _next;

		public ExpenseHandler(IExpenseApprover expenseApprover)
		{
			_approver = expenseApprover;
			_next = EndOfChainExpenseHandler.Instance;
		}

		public ApprovalResponse Approve(IExpenseReport expenseReport)
		{
			ApprovalResponse response = _approver.ApproveExpense(expenseReport);

			if (response == ApprovalResponse.BeyondApprovalLimit)
			{
				return _next.Approve(expenseReport);
			}

			return response;
		}

		public void RegisterNext(IExpenseHandler next)
		{
			_next = next;
		}
	}

This class will need an IExpenseApprover in its constructor. This approver is an Employee just like before. The constructor makes sure that there is always a special end of chain Employee in the approval chain through the EndOfChainExpenseHandler class. The Approve method receives an expense report. We ask the approver if they are able to approver the expense. If not, then we go to the next person in the hierarchy, i.e. to the “next” variable.

The implementation of the EndOfChainExpenseHandler class follows below. It also implements the IExpenseHandler method and it represents – as the name implies – the last member in the approval hierarchy. Its Instance property returns this special member of the chain according to the singleton pattern – more on that here.

public class EndOfChainExpenseHandler : IExpenseHandler
	{
		private EndOfChainExpenseHandler() { }

		public static EndOfChainExpenseHandler Instance
		{
			get { return _instance; }
		}

		public ApprovalResponse Approve(IExpenseReport expenseReport)
		{
			return ApprovalResponse.Denied;
		}

		public void RegisterNext(IExpenseHandler next)
		{
			throw new InvalidOperationException("End of chain handler must be the end of the chain!");
		}

		private static readonly EndOfChainExpenseHandler _instance = new EndOfChainExpenseHandler();
	}

The purpose of this class is to make sure that if the last person in the hierarchy, i.e. the President, is unable to approve the report then it is not passed on to a null reference – as there’s nobody above the President – but that there’s an automatic message handler that gives some default answer. Here we follow the null object pattern. In this case we reject the expense in the Approve method. If we made it this far in the approval chain then the expense must be rejected.

The revised Main method looks as follows:

static void Main(string[] args)
{
	ExpenseHandler william = new ExpenseHandler(new Employee("William Worker", Decimal.Zero));
	ExpenseHandler mary = new ExpenseHandler(new Employee("Mary Manager", new Decimal(1000)));
	ExpenseHandler victor = new ExpenseHandler(new Employee("Victor Vicepres", new Decimal(5000)));
	ExpenseHandler paula = new ExpenseHandler(new Employee("Paula President", new Decimal(20000)));

	william.RegisterNext(mary);
	mary.RegisterNext(victor);
	victor.RegisterNext(paula);

	Decimal expenseReportAmount;
	if (ConsoleInput.TryReadDecimal("Expense report amount:", out expenseReportAmount))
	{
		IExpenseReport expense = new ExpenseReport(expenseReportAmount);
		ApprovalResponse response = william.Approve(expense);
		Console.WriteLine("The request was {0}.", response);
	}
        Console.ReadKey();
}

You’ll see that we have not registered anyone for the President. This is where it becomes important that we set up a default end of chain approver in the ExpenseHandler constructor.

This is a significantly smaller amount of code than before. We start off by wrapping our employees into expense handlers, so each employee becomes an expense handler. Instead of putting them in a list we register the next employee in the hierarchy for each of them. Then as before we read the user’s input from the console, create an expense report and then we go to the first approver in the chain – william. The response from william will be abstracted away in the management chain we set up through the RegisterNext method.

Build and run the application. Enter 1000 and you’ll see that it is approved. Enter 30000 and you’ll see that it is rejected and the caller is oblivious of who and why rejected the request.

So this is the Chain of Responsibility pattern for you!

View the list of posts on Architecture and Patterns here.

ultimatemindsettoday

A great WordPress.com site

Elliot Balynn's Blog

A directory of wonderful thoughts

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: