Design patterns and practices in .NET: the Strategy Pattern

Introduction

The strategy pattern is one of the simplest patterns to implement. Have you ever written code with ugly if-else statements where you check some condition and then call another method accordingly? Even worse: have you written if-else statements to check the type of an object and then called another method depending on that? That’s not really object-oriented, right? The strategy pattern will help you clean up the mess by turning the if statements into objects – aka strategies – where the objects implement the same interface. Therefore they can be injected into another object that has a dependency of that interface and which will have no knowledge of the actual concrete type.

Read more of this post

Advertisement

Design patterns and practices in .NET: the Factory Patterns – concrete, static, abstract

Introduction

Factories are extremely popular among design patterns. I have never seen any reliable statistics on the usage of patterns but factories must be among the top three most used patterns. However, that is not to say that they are used correctly. Many developers misunderstand factories to factor out chunks of code to other classes where the factored-out code is encapsulated into a static method as follows:

double cost = CostFactory.Calculate(input params);

Read more of this post

Design patterns and practices in .NET: the Decorator design pattern

Introduction

The Decorator pattern aims to extend the functionality of objects at runtime. It achieves this goal by wrapping the object in a decorator class leaving the original object intact. The result is an enhanced implementation of the object which does not break any client code that’s using the object.

It is an alternative solution to subclassing: you can always create subclasses to an object to extend and modify its functionality but that can result in class-explosion. Class-explosion means that you create a large number of concrete classes from a base class to allow for the combination of different possible behaviour types. The result is a bloated class structure and a hard-to-maintain application.

The pattern supports the Open/Closed principle of SOLID software design: you don’t change the implementation of an existing object. Instead, you modify the object using a wrapper decorator class. All this happens dynamically at runtime, i.e. this is not a design time implementation. This yields another benefit: flexible design. Our application will be flexible enough to take on new functionality to meet changing requirements.

When is this pattern most applicable?

  • Legacy systems: changing legacy code can be nasty. It’s easier to modify existing code with decorators
  • Add functionality to controls in Windows Forms / WPF
  • Sealed classes: the pattern lets you change these classes despite they’re sealed

The key to understanding this pattern is wrapping: the decorator class behaves just like the object you’re trying to change by behaving like a wrapper of that object. The decorator will therefore have a reference to that object in its class structure. The pattern is also called the Wrapper pattern for exactly this reason. You can even have a chain of decorators by wrapping the decorator of the decorator of the decorator etc.

Demo with a Base Class

Fire up Visual Studio 2010 or 2012 and create a new Console application with the name you want. We’ll simulate a travel agency that offers 3 specific types of vacations: Recreation, Beach, Activity. Insert a base abstract class called Vacation:

public abstract class Vacation
	{
		public abstract string Description { get; }
		public abstract int Price { get; }
	}

Insert the following concrete classes:

public class Beach : Vacation
	{
		public override string Description
		{
			get { return "Beach"; }
		}

		public override int Price
		{
			get
			{
				return 2;
			}
		}
	}
public class Activity : Vacation
	{
		public override string Description
		{
			get { return "Activity"; }
		}

		public override int Price
		{
			get { return 4; }
		}
	}
public class Recreation : Vacation
	{
		public override string Description
		{
			get { return "Recreation"; }
		}

		public override int Price
		{
			get { return 3; }
		}
	}

The Main method in Program.cs is very simple:

static void Main(string[] args)
		{
			Beach beach = new Beach();

			Console.WriteLine(beach.Description);
			Console.WriteLine("Price: {0}", beach.Price);
			Console.ReadKey();
		}

I believe all is clear so far. Run the programme to see the output.

As time goes by customers want to add extras to their vacations: private pool, all-inclusive, massage etc. All of these can be added to each vacation type. So you start creating concrete classes such as BeachWithPool, BeachWithPoolAndMassage, ActivityWithPoolAndMassageAndAllInclusive, right?

Well, no, not really. This would be result in the aforementioned class-explosion. The amount of concrete classes in the application would grow exponentially as we add more and more extras and vacation types. This clearly cannot be maintained. Instead we’ll use the decorator pattern to decorate the concrete types with the extras.

Go ahead and insert the following decorator class:

public class VacationDecorator : Vacation
	{
		private Vacation _vacation;

		public VacationDecorator(Vacation vacation)
		{
			_vacation = vacation;
		}

		public Vacation Vacation
		{
			get { return _vacation; }
		}

		public override string Description
		{
			get { return _vacation.Description; }
		}

		public override int Price
		{
			get { return _vacation.Price; }
		}
	}

Note that the decorator also derives from the Vacation abstract class. The decorator delegates the overridden implemented getters to its wrapped Vacation object. The wrapped Vacation object is the one that’s going to be decorated. This will be the base class for the concrete decorators. So let’s start with the PrivatePool decorator:

public class PrivatePool : VacationDecorator
	{
		public PrivatePool(Vacation vacation) : base(vacation){}

		public override string Description
		{
			get
			{
				return string.Concat(base.Vacation.Description, ", Private pool.");
			}
		}

		public override int Price
		{
			get
			{
				return base.Vacation.Price + 2;
			}
		}
	}

This concrete decorator derives from the VacationDecorator class. It overrides the Description and Price property getters by extending those of the wrapped Vacation object. Let’s try to add a private pool to our beach holiday in Program.cs:

static void Main(string[] args)
		{
			Vacation beach = new Beach();
			beach = new PrivatePool(beach);

			Console.WriteLine(beach.Description);
			Console.WriteLine("Price: {0}", beach.Price);
			Console.ReadKey();
		}

Note that we first create a new Beach object, but declare its type as Vacation. Then we take the PrivatePool decorator and use it as a wrapper for the Beach. The rest of the Main method has remained unchanged. Run the programme and you’ll see that the description and total price include the Beach and PrivatePool descriptions and prices. Note that when we wrap the Beach object in the PrivatePool decorator it becomes of type PrivatePool instead of the original Beach.

Let’s create two more decorators:

public class Massage : VacationDecorator
	{
		public Massage(Vacation vacation) : base(vacation){}

		public override string Description
		{
			get
			{
				return string.Concat(base.Vacation.Description, ", Massage.");
			}
		}

		public override int Price
		{
			get
			{
				return base.Vacation.Price + 1;
			}
		}
	}
public class AllInclusive : VacationDecorator
	{
		public AllInclusive(Vacation vacation) : base(vacation)
		{}

		public override string Description
		{
			get
			{
				return string.Concat(base.Vacation.Description, ", All inclusive.");
			}
		}

		public override int Price
		{
			get
			{
				return base.Vacation.Price + 3;
			}
		}
	}

These two decorators have the same structure as PrivatePool, but the description and price getters have been modified of course. We’re now ready to add the all-inclusive and massage extras to our Beach vacation:

static void Main(string[] args)
		{
			Vacation beach = new Beach();
			beach = new PrivatePool(beach);
			beach = new AllInclusive(beach);
			beach = new Massage(beach);

			Console.WriteLine(beach.Description);
			Console.WriteLine("Price: {0}", beach.Price);
			Console.ReadKey();
		}

We keep wrapping the decorators until the original Beach object has been wrapped in a PrivatePool, an AllInclusive and a Massage decorator. The final type is Massage. The call to the Description and Price property getters will simply keep going “upwards” in the decorator chain. Run the programme and you’ll see that the description and price getters include all 4 inputs.

Now if the travel agency wants to introduce a new type of extra, all they need to do is to build a new concrete class deriving from the VacationDecorator.

The original Beach class is completely unaware of the presence of decorators. In addition, we can mix and match vacations types with their decorators. Our class structure is easy to extend and maintain.

Demo with an interface

You can apply the decorator pattern to interface-type abstractions as well. As you now understand the components of the pattern let’s go through one quick example.

Insert a class called Product and an interface called IProductService. Leave the product class empty. Insert a method into the interface:

public interface IProductService
	{
		IEnumerable<Product> GetProducts();
	}

Add a class called ProductService that implements IProductService:

public class ProductService : IProductService
	{
		public IEnumerable<Product> GetProducts()
		{
			return new List<Product>();
		}
	}

Using poor man’s dependency injection we can use the components as follows:

IProductService productService = new ProductService();
IEnumerable<Product> products = productService.GetProducts();
Console.ReadKey();

Nothing awfully complicated there I hope. Let’s say that you want to add caching to the Product service so that you don’t need to ask the product repository for the list of products every time. One option is of course to add caching directly into the body of the implemented GetProducts method. However, that is not the most optimal decision: it goes against the Single Responsibility Principle and reduces meaningful testability. It’s not straightforward to unit test a method that caches the results in its body. When you run the unit test twice, then you may not be able to get a reliable result from the method as it simply returns the cached outcome. Injecting some kind of caching strategy is a good way to go, check out the related Adapter pattern for more.

However, here we’ll take another approach. We want to extend the functionality of the Product service with a decorator. So let’s follow the same path as we did in the base class demo. Insert a decorator base as follows:

public class ProductServiceDecorator : IProductService
	{
		private readonly IProductService _productService;

		public ProductServiceDecorator(IProductService productService)
		{
			_productService = productService;
		}

		public IProductService ProductService { get { return _productService; } }

		public virtual IEnumerable<Product> GetProducts()
		{
			return _productService.GetProducts();
		}
	}

We follow the same principle as with the VacationDecorator class: we wrap an IProductService and call upon its implementation of GetProducts(). Let’s add the following cache decorator – you’ll need to add a reference to System.Runtime.Caching in order to have access to the ObjectCache class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Caching;
using System.Text;
using System.Threading.Tasks;

namespace Decorator
{
	public class ProductServiceCacheDecorator : ProductServiceDecorator
	{

		public ProductServiceCacheDecorator(IProductService productService)
			: base(productService)
		{ }

		public override IEnumerable<Product> GetProducts()
		{
			ObjectCache cache = MemoryCache.Default;
			string key = "products";
			if (cache.Contains(key))
			{
				return (IEnumerable<Product>)cache[key];
			}
			else
			{
				IEnumerable<Product> products = base.ProductService.GetProducts();
				CacheItemPolicy policy = new CacheItemPolicy();
				policy.AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddMinutes(1));
				cache.Add(key, products, policy);
				return products;
			}
		}
	}
}

We check the cache for the presence of a key. If it’s there then retrieve its contents otherwise ask the IProductRepository of the decorator base to carry out the query to the repository and cache the results. You can use these components as follows:

IProductService productService = new ProductService();
productService = new ProductServiceCacheDecorator(productService);
IEnumerable<Product> products = productService.GetProducts();
Console.ReadKey();

Run the programme and you’ll see that ProductServiceCacheDecorator takes over, runs the caching strategy and retrieves the products from the wrapped IProductService object.

View the list of posts on Architecture and Patterns here.

Design patterns and practices in .NET: the Service Locator anti-pattern

Introduction

The main responsibility of a Service Locator is to serve instances of services when consumers request them. The pattern is strongly linked to Dependency Injection and was introduced by Martin Fowler here.

The most common implementation of the pattern introduces a static factory. This factory can be configured with concrete services in the composition root of the application, such as global.asax, Main, etc., depending on the type of the application you’re developing. In other words the configuration happens before the first consumer can use it to extract a concrete service. Here you can think of a service as roughly equal to a dependency: the CustomerController has a dependency on ICustomerService. CustomerService has a dependency on ICustromerRepository etc. So when a concrete implementation of the abstraction is needed then the caller tries to grab it from the Service Locator.

A Service Locator is quite similar to Inversion-of-Control (IoC) containers at first. If you’re familiar with some IoCs such as StructureMap or CastleWindsor, then you’ll know that you can register your concrete types in the composition root. In StructureMap you can do this explicitly as follows:

x.For<ICustomerService>().Use<ConcreteCustomerService>();

The Service Locator configuration starts off in a similar manner. It’s essentially a dictionary of abstractions and their desired concrete types: ICustomerRepository – CustomerRepository; IProductService – ProductService. This is perfectly legitimate to do from the composition root. As we will see later consulting the service locator elsewhere in the application for concrete services is an anti-pattern.

Demo

We’ll simulate a dependency between the CustomerService and CustomerRepository classes where CustomerService requires a customer repository to consult the database for queries on the customer domain. Open Visual Studio and add the following standard generic implementation of a ServiceLocator:

public static class ServiceLocator
{
	private readonly static Dictionary<Type, object> _configuredServices = new Dictionary<Type, object>();

	public static T GetConfiguredService<T>()
	{
		return (T)ServiceLocator._configuredServices[typeof(T)];
	}

	public static void Register<T>(T service)
	{
		ServiceLocator._configuredServices[typeof(T)] = service;
	}
}

This is a very minimalistic implementation of the Service Locator. It’s void of exception handling, guard clauses, loading the dependency graph from an XML file but those features only add noise to the main discussion. The dependency map is stored in the private dictionary and the Register method is used, as you’ve probably guessed it, to register dependencies. It is analogous to the .For and .Use extension methods in the StructureMap example above. Let’s add the following interfaces and classes to see how the locator can be used:

public class Customer
{
}
public interface ICustomerService
{
	Customer GetCustomer(int id);
}
public interface ICustomerRepository
{
	Customer GetCustomerFromDatabase(int id);
}
public class CustomerRepository : ICustomerRepository
{
	public Customer GetCustomerFromDatabase(int id)
	{
		return new Customer();
	}
}
public class CustomerService : ICustomerService
{
	private ICustomerRepository _customerRepository;

	public CustomerService()
	{
		_customerRepository = ServiceLocator.GetConfiguredService<ICustomerRepository>();
	}

	public Customer GetCustomer(int id)
	{
		return _customerRepository.GetCustomerFromDatabase(id);
	}
}

You should be able to follow along this far. The CustomerService class resolves its own dependency using the ServiceLocator. You can configure the locator in Main as follows:

static void Main(string[] args)
{
	ServiceLocator.Register<ICustomerRepository>(new CustomerRepository());
	Customer c = new CustomerService().GetCustomer(54);
}

Main represents the composition root of a Console application so that’s where you can register the dependency graph. Step through the app with F11 and you’ll see that CustomerRepository is registered and retrieved as expected.

The CustomerService class can resolve its own dependency on ICustomerRepository, so what’s the problem? We can register our concrete implementations, retrieve the stored implementation where it’s needed, register Mock objects as concrete types in a Test Driven Design scenario, program against abstractions, write maintainable code, support late binding by changing the registration, so you’re a happy bunny, right? You shouldn’t be as the ServiceLocator class has a negative effect on the re-usability of the classes that consume it:

  • The ServiceLocator dependency will drag along if you try to re-use a class with a call to the locator
  • It is not obvious for external clients calling CustomerService() that Dependency Injection is used

The CustomerService will loosely depend on CustomerRepository through the ICustomerRepository interface. This is perfectly legitimate and valid. However, it will be tightly coupled to the ServiceLocator class. Here’s the dependency graph:

Dependency graph with service locator

If you want to distribute the CustomerService class then you’ll have to attach the ServiceLocator class to the package. It must come along even if the person that wants to use your class is not intending to use the ServiceLocator class in any way because they have their own Dependency Injection solution, such as StructureMap or CastleWindsor. Also, the consumer will need to set up ServiceLocator in the composition root otherwise they will get an exception. As the ServiceLocator may well reside in a different module, even that module must be redistributed for the CustomerService to be usable.

ProductService forces its users to follow the Dependency Injection strategy employed within it. There’s no room for other strategies unfortunately. Developers must simply accept the existence of the service locator. Also, there’s no way of telling that there’s a direct dependency just by looking at its signature which is what consumers will see first when creating a new CustomerService object. If the consumer doesn’t set up ServiceLocator appropriately then they will get an exception when using the CustomerService constructor. Depending on the exception handling strategy all they may get is a KeyNotFoundException. The consumer will then ask the questions: what key? Why is it not found? What are you talking about? WHY YOU NO WORK!!??? The consumer must know about the internals of the ConsumerService class which usually indicates a higher-than-desired level of coupling.

We can therefore rule out this patterns as it brings with it a fully redundant dependency which we can get rid of easily using constructor injection:

public CustomerService(ICustomerRepository customerRepository)
{
	_customerRepository = customerRepository;
}

There’s simply no advantage with this pattern that cannot be solved with an alternative solution such as constructor injection coupled with an IoC container. ProductService as it stands is not self-documenting. Its signature does not reveal anything about its dependency needs. Imagine that you download this API from NuGet and call CustomerService service = new CustomerService(). Your assumption would be that this is a fairly simple class that does not have any external dependencies which is not true as it turns out.

You can misuse IoC containers in the same way actually. It’s fine to use IoCs to resolve your dependencies “behind the scenes” but they – or at least some of them – allow the users to fetch concrete types from the container. In StructureMap you’d do it as follows:

StructureMap.ObjectFactory.Container.GetInstance<CustomerRepository>()

You should avoid using this type of dependency resolution for the same reasons why you wouldn’t use a ServiceLocator and its GetConfiguredService method.

Note that this pattern being an anti-pattern is a controversial topic. You can check out this post that offers another viewpoint and argues that Service Locator is indeed a proper design pattern.

View the list of posts on Architecture and Patterns here.

Design patterns and practices in .NET: the Prototype pattern

Introduction

The formal definition of the prototype pattern is the following: specify the kinds of objects to create using a prototypical instance and create new objects by copying this prototype.

What this basically says is instead of using ‘new’ to create a new object we’re going to use a prototype, an existing object to specify the new objects we’re going to create. Then we create new objects by copying from this prototype. So the prototype is a master, a blueprint and the other objects we create will be copies of that object. Another word that can be used instead of ‘copy’ is ‘clone’. So this pattern is very much about cloning objects. A real life example could be a photocopy machine that can get you exact copies of the original document instead of asking the original source to send you a brand new one. Making a copy in this case is a cheaper and a lot more efficient way of getting a copy of the object, i.e. the document.

The implementation of the pattern is very easy as you’ll see, almost confusingly easy. You may even ask yourself the question: is this really a pattern??

Demo

Open Visual Studio and create a new console application. We’ll simulate a reader that analyses the contents of web pages. You’ll need a reference to the System.Net.Http library. Insert the following class:

public class DocumentReader
{
	private string _pageTitle;
	private int _headerCount;
	private string _bodyContent;

	public DocumentReader(Uri uri)
	{
		HttpClient httpClient = new HttpClient();
		Task<string> contents = httpClient.GetStringAsync(uri);
		string stringContents = contents.Result;
		Analyse(stringContents);
	}

	private void Analyse(string stringContents)
	{
		_pageTitle = "Homepage";
		_headerCount = 2;
		_bodyContent = "Welcome to my homepage";
	}

	public void PrintPageData()
	{
		Console.WriteLine("Page title: {0}, header count: {1}, body: {2}", _pageTitle, _headerCount, _bodyContent);
	}
}

So we send in a URI to the constructor which downloads the string content of that URI. The Analyse method then fakes a true string content analysis. PrintPageData simply prints these findings in the console.

You can use this reader from Main as follows:

static void Main(string[] args)
		{
			DocumentReader reader = new DocumentReader(new Uri("http://bbc.co.uk"));
			reader.PrintPageData();
			Console.ReadKey();
		}

In a true implementation of the document reader we would probably parse the HTML document and try to find the real title, the body contents, the headers and lot more properties. However, even a true implementation of the Analyse method would run a lot faster than the actual download in the httpClient.GetStringAsync(uri) call. You’ll see that there’s a delay before we see the printout. The delay is not very significant as the HttpClient object coupled with the Task library is very efficient. However, we don’t want to cause the same delay if we need a copy of the page data.

The first solution is of course to create a new copy of the document reader, pass in bbc.co.uk and let it get the page data again. In other words we need to make the web request twice which is probably not very clever if we need a copy of the data that’s already been constructed. This is where the prototype pattern comes into the picture: we can make a copy of the document reader without having to perform the HTTP web request.

As it turns out the prototype pattern can be implemented using an interface available in .NET, the IClonable interface. The interface itself represents the abstract prototype; by the implementing object will itself be of type IClonable, i.e. a concrete prototype. The prototype will need to define a method which makes a copy of the object. The IClonable interface has a Clone() method which has this very purpose. The concrete prototype will have the ability to copy itself in the Clone() method where you can choose between creating a deep copy or a shallow copy, more on this later.

Let’s see how it’s done:

public class DocumentReader : ICloneable
{
	private string _pageTitle;
	private int _headerCount;
	private string _bodyContent;

	public DocumentReader(Uri uri)
	{
		HttpClient httpClient = new HttpClient();
		Task<string> contents = httpClient.GetStringAsync(uri);
		string stringContents = contents.Result;
		Analyse(stringContents);
	}

	private void Analyse(string stringContents)
	{
		_pageTitle = "Homepage";
		_headerCount = 2;
		_bodyContent = "Welcome to my homepage";
	}

	public void PrintPageData()
	{
		Console.WriteLine("Page title: {0}, header count: {1}, body: {2}", _pageTitle, _headerCount, _bodyContent);
	}

	public object Clone()
	{
		return MemberwiseClone();
	}
}

The interface has one member to be implemented which is the Clone method. Every object in .NET has built-in method called MemberwiseClone which suits our purposes just fine. It is going to copy all the data that exist in the original object, i.e. the prototype. It returns an object with the same data inside. However, be careful with this method as it cannot copy complex objects. Say that the DocumentReader had another object, like WebPage which in turn has its own private members, then MemberwiseClone will not copy those. In other words it creates a shallow copy as opposed to a deep copy. It copies the reference of complex objects instead of the objects themselves. However, it may be enough depending on what you want to achieve. Probably reading data from the same reference is OK, but not making changes to that reference. If you want perform a deep copy then you’ll have to manually make a memberwise clone of the entire object graph.

You can use this code in Main as follows:

static void Main(string[] args)
{
	DocumentReader reader = new DocumentReader(new Uri("http://bbc.co.uk"));
	reader.PrintPageData();

	DocumentReader readerClone = reader.Clone() as DocumentReader;
	readerClone.PrintPageData();

	Console.ReadKey();
}

Go ahead and run this and you’ll see that there’s no delay at all before the second printout appears in the console window.

This is the easiest implementation of the prototype pattern in .NET. It doesn’t make any sense to go through the object construction again and make the second web request.

Another similar scenario would have been making the same database calls. Often this is not necessary if all you need is the same set of data.

Yet another example is when you need a copy of an object with the same state. Imagine an object which has several private fields and those fields can be manipulated with public objects such as the following:

  1. TurnRight(int speed)
  2. GoStraightAhead()
  3. Stop()
  4. BuySomethingInTheShop(int productNumber)

These methods can modify the internal state of the object. In case you need another object with the same internal state then you’d need to go through the same steps as above. You’ll need to keep track of these steps and the user inputs as well.

A better solution is to implement the IClonable interface and clone the original object. You’ll then have access to the same state as in the prototype.

View the list of posts on Architecture and Patterns here.

Design patterns and practices in .NET: the Observer pattern

Introduction

As its name implies the pattern has to do with the interaction between two or more objects. The objects may or may not be related, but one object is interested in the changes of the other object. In other words there’s some kind of dependency between them. Changing one object may require changing one or more other objects. The most interesting case, however, is when changing an object should allow notification to others without any knowledge of them.

The pattern is used extensively in .NET:

  • GUI controls: events such as OnClick are handled through event handlers which are waiting for changes in the control
  • Data binding of controls: e.g. a GridView control in ASP.NET web forms can be bound to a data source upon which its item templates will be filled with data from the source
  • File watchers: you can monitor folders and files for changes. You can wire up the events so that you get notified if somebody has added a file to a certain folder

Starting point

Open Visual Studio and start a new Console application. We’ll simulate a financial application where people trade commodities, like in the Kansas City Board of Trade and similar exchanges. Create a new object called Commodity:

public class Commodity
{
	public string Name { get; set; }
	public decimal Price { get; set; }
}

Insert the following rudimentary repository:

public class CommodityRepository
{
	public IEnumerable<Commodity> GetAllCommodities()
	{
		return new List<Commodity>()
		{
			new Commodity(){Name = "milk", Price= 1}
			, new Commodity() {Name = "milk", Price = 1.2m}
			, new Commodity() {Name = "milk", Price = 1.3m}
			, new Commodity() {Name = "cocoa", Price = 2.1m}
			, new Commodity() {Name = "milk", Price = 3.2m}
			, new Commodity() {Name = "cocoa", Price = 2.9m}
			, new Commodity() {Name = "milk", Price = 1.8m}
			, new Commodity() {Name = "cocoa", Price = 1.7m} 
		};
	}
}

Insert the following in Main:

static void Main(string[] args)
{
	RunNaiveExample();
	Console.ReadKey();
}

private static void RunNaiveExample()
{
	IEnumerable<Commodity> commodities = new CommodityRepository().GetAllCommodities();
	foreach (Commodity commodity in commodities)
	{
		if (commodity.Name == "cocoa")
		{
			Console.WriteLine("The current price of cocoa is {0}", commodity.Price);
		}

		if (commodity.Name == "milk" && commodity.Price > 2m)
		{
			Console.WriteLine("The price of milk has now reached {0}", commodity.Price);
		}
	}
}

The intent is quite simple here, right? We’re looping through the list of commodities in the list and if we find something interesting then we print it out in the console. The multiple entries in the Commodities list simulates that we ask some service periodically, like in a ticker. This is probably the simplest version of commodity monitoring. We perform one or more actions based on the filtering in the if statements. Run the app to see the output: milk exceeds the target price of 2 once, and cocoa appears 3 times.

Even in this short application we can see several issues, particularly with the separation of concerns. The loop in Main corresponds to a ticker. However, a ticker doesn’t need to know that we’re monitoring specific commodities. It doesn’t need to know about the price of milk and cocoa to perform its job. All it needs to do is to read the commodities one by one and report on them. Also, we’re mixing prices in the loop: the milk price has nothing to do with the cocoa price – at least not from a software design point of view.

These are all independent actions that are mixed together in the same programme. In case we want to monitor a different commodity then we have to extend the foreach loop, i.e. we have to modify the main application.

The observer pattern allows us to separate out those filters, which are called observers, and the actions that they’re taking.

Events and delegates

.NET supports events and delegates which are excellent candidates for implementing the observer pattern. The event is created on the subject and allows for the registration of observers through a delegate callback mechanism. The observers will provide implementations for the delegate methods that will be called by the subject when the event is raised.

If you’re familiar with .NET desktop apps and ASP.NET web forms then you must have seen a lot of events: the standard button has a click event – among others – and a corresponding OnClick event handler. Event handlers are also called callbacks. As events and delegates are built-in objects in .NET there’s nothing stopping you from implementing the observer pattern using your own events and delegates. You can also pass event arguments to event handlers.

Let’s start our implementation with the event arguments. All such objects must derive from the EventArgs object:

public class CommodityChangeEventArgs : EventArgs
{
	public Commodity Commodity { get; set; }

	public CommodityChangeEventArgs(Commodity commodity)
	{
		this.Commodity = commodity;
	}
}

So when there’s a change in the commodity, its price, its name or any other property, then we can send it along with all other properties that can be interesting to the event handler waiting for such a change. An object waiting for such a change event might be the following CommodityMonitor object:

public class CommodityMonitor
{
	private Commodity _commodity;
	public event EventHandler<CommodityChangeEventArgs> CommodityChange;

	public Commodity Commodity
	{
		get
		{
			return _commodity;
		}
		set
		{
			_commodity = value;
			this.OnCommodityChange(new CommodityChangeEventArgs(_commodity));
		}
	}

	protected virtual void OnCommodityChange(CommodityChangeEventArgs e)
	{
		if (CommodityChange != null)
		{
			CommodityChange(this, e);
		}
	}
}

As the CommodityMonitor monitors commodities it will need a Commodity object. If you are new to events then the event declaration might look unusual but that is how we register an observer. The OnCommodityChange method has the notifier role in this setup and it accepts the appropriate event arguments. This method is called by the Commodity setter: if there’s a change then run the notification logic. The notifier then checks if the observer has been set, i.e. whether it’s null or not. If yes then it raises the event. Events have a common pair of arguments: the sender, i.e. the object that sends the change event and the event arguments. The sender will simply be “this”, i.e. the CommodityMonitor object. It sends out a signal saying that something has changed. What has changed? Anyone who’s interested can find it out from the event arguments. Any objects can sign up as observers and they will all be notified.

Here we only set up one event, but an object can raise many events. We may raise separate events for price changes, name changes, weather changes, football score changes etc. They can have their own event arguments as well. So this model provides a high level of granularity and object orientation.

The next thing we want to do is create our observers. We’re interested in milk and cocoa so we’ll insert two observers. We’ll start with MilkObserver:

public class MilkObserver
{
	public MilkObserver(CommodityMonitor monitor)
	{
		monitor.CommodityChange += monitor_CommodityChange;
	}

	void monitor_CommodityChange(object sender, CommodityChangeEventArgs e)
	{
		CheckFilter(e.Commodity);
	}

	private void CheckFilter(Commodity commodity)
	{
		if (commodity.Name == "milk" && commodity.Price > 2m)
		{
			Console.WriteLine("The price of milk has now reached {0}", commodity.Price);
		}
	}
}

The funny looking monitor.CommodityChange += monitor_CommodityChange part performs the registration. We want to register the milk observer to the CommodityChange event of the monitor. It is the monitor_CommodityChange that’s going to handle the event. Check its signature, it follows the sender + event args standard. The event handler must have this signature otherwise it cannot be registered as the event handler of the commodity change event. Furthermore the type of the event arguments must match the type declared in CommodityMonitor.

The plus sign declares that we want to register. We could revoke the registration with a minus: monitor.CommodityChange -= monitor_CommodityChange if we are not interested in the changes any more. In fact as you type ‘+’ then IntelliSense will give you the option to create a new event handler – or select an existing one if there’s any with the correct signature.

So what’s happening if the event is raised? The CheckFilter is run which accepts a Commodity object. The filter will be familiar to you from the first naive implementation: we check the name and the price and if it matches the criteria then we print out the message in the console.

What’s even more important I think is that we turned our original primitives-based solution into an object oriented one. We raised an if-statement in the client to a proper object acknowledging its importance in our domain model. It is now an independent object that can be tested separately.

The CocoaObserver looks similar:

public class CocoaObserver
{
	public CocoaObserver(CommodityMonitor monitor)
	{
		monitor.CommodityChange += monitor_CommodityChange;
	}

	void monitor_CommodityChange(object sender, CommodityChangeEventArgs e)
	{
		CheckFilter(e.Commodity);
	}

	private void CheckFilter(Commodity commodity)
	{
		if (commodity.Name == "cocoa")
		{
			Console.WriteLine("The current price of cocoa is {0}", commodity.Price);
		}
	}
}

Insert the following method in Program.cs and call it from Main:

private static void RunEventBasedExample()
{
	CommodityMonitor monitor = new CommodityMonitor();

	CocoaObserver cocoaObserver = new CocoaObserver(monitor);
	MilkObserver milkObserver = new MilkObserver(monitor);

	IEnumerable<Commodity> commodities = new CommodityRepository().GetAllCommodities();
	foreach (Commodity commodity in commodities)
	{
		monitor.Commodity = commodity;
	}
}

We create a new commodity monitor and then sign up our two observers. We could add as many observers as we want to. Then we run through our list of commodities and set them as the Commodity property of the monitor object. The property setter then raises the event as explained above. Run through the code by setting breakpoints and pressing F11 in order to follow the exact code execution.

IObserver-based solution

.NET4 introduced a new type of interface: IObserver of T and IObservable of T. As the names of the interfaces imply the CommodityMonitor class will have something to do with the IObservable interface as it can be observed. In fact CommodityMonitor will implement this interface. The Milk and CocoaObservers will implement the IObserver interface.

The IObserver interface will force us to implement several methods:

  • OnCompleted: indicates that there will be no more changes to the subject
  • OnError: when there’s an error in processing the subject
  • OnNext: when getting the next value of the subject, equivalent to the Commodity setter in the event-based solution

IObservable has a Subscribe method that must be implemented. It represents the registration of observers and returns an IDisposable object. As it returns an IDisposable it will be easier for us to release an observer from the subject properly. This is actually a drawback of the event-based method above as we only subscribe to the event but never release the observer. We think that the garbage collector will take care of that but that’s not the case; there’s still a reference to the observer from the subject so this resource is not released for garbage collection. With the Subscribe method we get a reference to the IDisposable method so that we can keep track of it and release it when we don’t use it any longer.

We’ll see in the demo how this is done.

This setup implements the “push” approach of the pattern: whenever there’s a change in the subject we push them out to the observers.

Let’s implement the pattern using these interfaces.

Here come the updated observers first. They are very simple; they implement the three methods in IObserver mentioned above. You’ll recognise the usual filter in the OnNext method. Recall that this runs when we get an update from the subject.

public class CocoaObserverModern : IObserver<Commodity>
{
	public void OnCompleted()
	{
		Console.WriteLine("Shop closed.");
	}

	public void OnError(Exception error)
	{
		Console.WriteLine("Oops: {0}", error.Message);
	}

	public void OnNext(Commodity commodity)
	{
		if (commodity.Name == "cocoa")
		{
			Console.WriteLine("The current price of cocoa is {0}", commodity.Price);
		}
	}
}

We send in the updated Commodity to the OnNext method so that we can check its properties. We’re also prepared to handle exceptions that occur in the commodity monitor during the update of the subject. Lastly we tell the user when we’re done updating the subjects.

public class MilkObserverModern : IObserver<Commodity>
{
	public void OnCompleted()
	{
		Console.WriteLine("Shop closed.");
	}

	public void OnError(Exception error)
	{
		Console.WriteLine("Oops: {0}", error.Message);
	}

	public void OnNext(Commodity commodity)
	{
		if (commodity.Name == "milk" && commodity.Price > 2m)
		{
			Console.WriteLine("The price of milk has now reached {0}", commodity.Price);
		}
	}
}

Insert a class called ObservableCommodity which is the IObservable version of the previous CommodityMonitor object:

public class ObservableCommodity : IObservable<Commodity>
{
        private List<IObserver<Commodity>> _observers = new List<IObserver<Commodity>>();
	private Commodity _commodity;
	public Commodity Commodity
	{
		get
		{
			return _commodity;
		}
		set
		{
			_commodity = value;
			this.Notify(_commodity);
		}
	}

	private void Notify(Commodity commodity)
	{
		foreach (IObserver<Commodity> observer in _observers)
		{
			if (commodity.Name == null || commodity.Price < 0)
			{
				observer.OnError(new Exception("Bad Commodity data"));
			}
			else
			{
				observer.OnNext(commodity);
			}
		}
	}

	private void Stop()
	{
		foreach (IObserver<Commodity> observer in _observers)
		{
			if (_observers.Contains(observer))
			{
				observer.OnCompleted();
			}
		}
		_observers.Clear();
	}


	public IDisposable Subscribe(IObserver<Commodity> observer)
	{
		if (!_observers.Contains(observer))
		{
			_observers.Add(observer);
		}
		return new Unsubscriber(_observers, observer);
	}

	private class Unsubscriber : IDisposable
	{
		private List<IObserver<Commodity>> _observers;
		private IObserver<Commodity> _observer;

		public Unsubscriber(List<IObserver<Commodity>> observers, IObserver<Commodity> observer)
		{
			_observers = observers;
			_observer = observer;
		}
		public void Dispose()
		{
			if (_observer != null && _observers.Contains(_observer))
			{
				_observers.Remove(_observer);
			}
		}
	}
}

This is more complicated than the CommodityMonitor class. As before we have the Commodity getter and setter. We call the Notify method in the setter. This method will notify each observer in some way: it calls the OnError method of the observer if the Commodity object has an invalid property. It also sends along an Exception object. Otherwise it just calls the OnNext method and sends in the commodity object.

Now check out the Subscribe method. As we said before it returns an IDisposable object. We add the incoming observer to the collection of observers, but we check first if the observer has been added before. We return an object which is the unsubscriber of the observer from the observers collection.

Check out the private Unsubscriber class. It implements the IDisposable interface meaning it has to implement the Dispose method. It holds a reference to the list of observers and the observer, both populated from the Subscribe method. In the Dispose method we check if the observer is not null and if it is contained by the observers list. If both conditions apply then we remove the observer from the observers list.

The Stop method of ObservableCommodity is not actually used. I’ve included it for your reference; it could be used when there are no more commodity objects in the collection. In that case we can call the OnCompleted method of each observer.

Let’s run our code. Insert the following method into Program.cs and call it from Main:

private static void RunModernObserableBasedApproach()
{
	ObservableCommodity oc = new ObservableCommodity();
	MilkObserverModern milkObserver = new MilkObserverModern();
	CocoaObserverModern cocoaObserver = new CocoaObserverModern();
	IEnumerable<Commodity> commodities = new CommodityRepository().GetAllCommodities();
	using (oc.Subscribe(milkObserver))
	{
		using (oc.Subscribe(cocoaObserver))
		{
			foreach (Commodity commodity in commodities)
			{
				oc.Commodity = commodity;
			}
		}
	}
}

This looks pretty much like the RunEventBasedExample method. We have our observable object and the two observers. We don’t need to send in the commodity monitor to the constructor of the observers this time. Observer registration is taken care of by the Subscribe method. We’re using “using” statements as Subscribe returns an IDisposable object. This technique will make sure that we release the observer from the subject.

Run the app and you’ll see that even the modern approach works fine and returns the same output as before.

View the list of posts on Architecture and Patterns here.

Design patterns and practices in .NET: the Bridge pattern

Introduction

This pattern was originally defined by the Gang of Four as follows: decouple an abstraction from its implementation so the two can vary independently.

You probably know what abstractions are: base classes and interfaces, i.e. objects to generalise our code and/or make a group of objects related in some way. We abstract away ideas that can have multiple concrete implementations. Normally if a class implements an interface or derives from an abstract superclass then the abstraction and the implementation are tightly coupled. If you change the structure of the interface, such as add a new method to it, then all implementations will need to change as well. The bridge pattern aims to decouple them so that we get rid of this coupling. We’ll introduce a higher level of abstraction to abstract away the implementation from the original abstraction. We’ll end up with two levels of abstraction instead of just one.

Let’s try and imagine a real-world example: a travel agent putting together different types of holiday in a brochure. The agency organises trips to 4 countries: Cyprus, Turkey, Greece and Italy. It also offers a couple of extras: private pool, free gym, all-inclusive and massage. The agency wants to show the full programme as follows:

  • Italy – private pool – free gym
  • Cyprus – private pool – free gym
  • Turkey – private pool – free gym
  • Greece – private pool – free gym
  • Italy – all inc – massage
  • Cyprus – all inc – massage
  • Turkey – all inc – massage
  • Greece – all inc – massage
  • …so on and so forth

In other words the agency wants to show the full combos as single items. You’ll see a lot of duplication here: the combination of extras is repeated several times, such as ‘all inc – massage’. However, the person putting together this brochure was committed to show all the options in one place. We can think of the concept ‘trip’ as the abstraction and the combos as the implementations: we can have Italy with private-pool-and-free-gym; we can have Italy with all-inclusive-and-massage; we can have Cyprus with private-pool-and-free-gym etc.

Another agent looks at this and ‘refactors’ the brochure. She realises that the offers can be simplified greatly to:

  • Cyprus
  • Turkey
  • Greece
  • Italy

with

  • private pool – free gym
  • all inc – massage

Now it’s easier to build combos: we can add new countries and new combinations of extras. In the first example if we introduce a new combination of extras, such as private-pool-with-massage then the agent will need to create 4 new items in the brochure, one for each country. We have a similar problem if we add a new country. In the second solution the client can choose how to combine the destination with the extra combos. It is not the agent, i.e. the developer, that builds all the combos, but the client.

Demo

In the demo we’ll simulate a building management application. Imagine that some authority is responsible for maintaining state-owned buildings and they need help with creating a manager application. Open Visual Studio and create a new console application. We’ll start with 3 basic domain objects with their own properties and a Print method in common:

public class Apartment
{
	public string Description { get; set; }
	public Dictionary<string, string> Rooms { get; set; }

	public Apartment()
	{
		Rooms = new Dictionary<string, string>();
	}

	public void Print()
	{
		Console.WriteLine("Apartment: ");
		Console.WriteLine(Description);
		foreach (KeyValuePair<string, string> room in Rooms)
		{
			Console.WriteLine(string.Concat("Room: ", room.Key, ", room description: ", room.Value));
		}
	}
}
public class House
{
	public string Description { get; set; }
	public string Owner { get; set; }
	public string Address { get; set; }

	public void Print()
	{
		Console.WriteLine("House: ");
		Console.WriteLine(string.Concat("Description: ", Description, " owner:  ", Owner, " address: ", Address));
	}
}
public class TrainStation
{
	public int NumberOfTrains { get; set; }
	public string Location { get; set; }
	public int NumberOfPassangers { get; set; }
	public string Director { get; set; }

	public void Print()
	{
		Console.WriteLine("Train station: ");
		Console.WriteLine(string.Concat("Number of trains: ", NumberOfTrains, ", Location: ", Location, ", number of passangers: ", NumberOfPassangers
			, ", director: ", Director));
	}
}

We construct and print the objects in Main as follows:

class Program
{
	static void Main(string[] args)
	{
		Apartment apartment = new Apartment();
		apartment.Description = "Nice apartment.";
		apartment.Rooms.Add("1/A", "Cozy little room");
		apartment.Rooms.Add("2/C", "To be renovated");
		apartment.Print();

		House house = new House();
		house.Address = "New Street";
		house.Description = "Large family home.";
		house.Owner = "Mr. Smith.";
		house.Print();

		TrainStation trainStation = new TrainStation();
		trainStation.Director = "Mr. Kovacs";
		trainStation.Location = "Budapest";
		trainStation.NumberOfPassangers = 100000;
		trainStation.NumberOfTrains = 100;
		trainStation.Print();

		Console.ReadKey();
	}
}

Run the app to see the output. Up to now this is extremely basic I guess. All domain objects have a different set of properties and structure. Also, there are a couple of similarities. They are definitely all buildings and they can be printed. The first step towards an abstraction – and so the bridge pattern – is to introduce an interface in the domain:

public interface IBuilding
{
	void Print();
}

Make the 3 domain objects implement the interface. In Main we can then have a list of IBuilding objects and call their Print method in a loop:

static void Main(string[] args)
{
	List<IBuilding> buildings = new List<IBuilding>();
	Apartment apartment = new Apartment();
	apartment.Description = "Nice apartment.";
	apartment.Rooms.Add("1/A", "Cozy little room");
	apartment.Rooms.Add("2/C", "To be renovated");
	buildings.Add(apartment);

	House house = new House();
	house.Address = "New Street";
	house.Description = "Large family home.";
	house.Owner = "Mr. Smith.";
	buildings.Add(house);

	TrainStation trainStation = new TrainStation();
	trainStation.Director = "Mr. Kovacs";
	trainStation.Location = "Budapest";
	trainStation.NumberOfPassangers = 100000;
	trainStation.NumberOfTrains = 100;
	buildings.Add(trainStation);

	foreach (IBuilding building in buildings)
	{
		building.Print();
	}

	Console.ReadKey();
}

Run the app and you should see the same output as before.

If the requirements stop here then we don’t need the bridge pattern. We only introduced a bit of abstraction to generalise our domain model. However, note that this is the first step towards the pattern: we now have the first level of abstraction and we’ll need a second if the requirements change.

As requirements do change in practice this is what we’ll simulate: the customer wants to be able to print out the objects in different styles and formats. A possible solution is to create a different type of House, or even derive from it, call it FormattedHouse and override the Print method according to the new requirements – need to make the Print method of House overridable. Make the same changes to the other 2 objects and then we end up with 6 domain objects. As we add new types of building we always have to create 2: one with a normal printout and one with the fancy style. And when the customer asks for yet another type of printout then we’ll have 9 domain objects where our domain should really only have 3.

We could prevent this with some kind of parameter, like “bool fancyPrint” leading to an if-else statement within the Print method. Then as we introduce new formatting types we may switch to an enumeration instead leading to an even longer if-else statement and the need to extend each and every Print() implementation as the enumeration grows. This is not good software engineering practice.

Instead we need another level of abstraction that takes care of the formatting of the printout. We still want to print the attributes of the domain objects but we want a formatter to take care of that. In addition as our objects have different structures we want to preserve the liberty of printing the specific properties of the domain objects. We don’t want to force the House object to have a NumberOfTrains property just to make the domains universal.

Let’s start out with the following formatter interface:

public interface IFormatter
{
    string Format(string key, string value);
}

This is quite simple and general: the key will be the formatting style, such as “Description: “, and the value is the value to be printed, such as House.Description.

We’ll need to inject this formatter to the Print method of each domain object, so update the IBuilding interface as follows:

public interface IBuilding
{
	void Print(IFormatter formatter);
}

Update each Print implementation to accept the IFormatter parameter, example:

public void Print(IFormatter formatter)

A short side note: if you want to force your domain objects to have a formatter then you will need to create an abstract base class that each domain object inherit from, such as BuildingBase. The constructor of the base class will accept an IFormatter so that you’ll need to update the constructor of each domain object to accept an IFormatter. However, here I’ll just stick to the interface solution.

Let’s update the Print method in each of the domain objects to use the formatter:

public class House : IBuilding
{
	public string Description { get; set; }
	public string Owner { get; set; }
	public string Address { get; set; }

	public void Print(IFormatter formatter)
	{
		Console.WriteLine(formatter.Format("Description: ", Description));
		Console.WriteLine(formatter.Format("Owner: ", Owner));
		Console.WriteLine(formatter.Format("Address: ", Address));
	}
}
public class TrainStation : IBuilding
{
	public int NumberOfTrains { get; set; }
	public string Location { get; set; }
	public int NumberOfPassangers { get; set; }
	public string Director { get; set; }

	public void Print(IFormatter formatter)
	{
		Console.WriteLine(formatter.Format("Number of trains: ", NumberOfTrains.ToString()));
		Console.WriteLine(formatter.Format("Location: ", Location));
		Console.WriteLine(formatter.Format("Number of passangers:", NumberOfPassangers.ToString()));
		Console.WriteLine(formatter.Format("Director: ", Director));
	}
}
public class Apartment : IBuilding
{
	public string Description { get; set; }
	public Dictionary<string, string> Rooms { get; set; }

	public Apartment()
	{
		Rooms = new Dictionary<string, string>();
	}

	public void Print(IFormatter formatter)
	{
		Console.WriteLine(formatter.Format("Description: ", Description));
		foreach (KeyValuePair<string, string> room in Rooms)
		{
			Console.WriteLine(string.Concat(formatter.Format("Room: ", room.Key), formatter.Format(", room description: ", room.Value)));
		}
	}
}

Now we’re ready for some implementations of the IFormatter interface. The most obvious choice is a standard formatter that prints the properties as in our previous solution:

class StandardFormatter : IFormatter
    {
        public string Format(string key, string value)
        {
            return string.Format("{0}: {1}", key, value);
        }
    }

The updated Main method looks like follows:

static void Main(string[] args)
{
	IFormatter formatter = new StandardFormatter();
	List<IBuilding> buildings = new List<IBuilding>();
	Apartment apartment = new Apartment();
	apartment.Description = "Nice apartment.";
	apartment.Rooms.Add("1/A", "Cozy little room");
	apartment.Rooms.Add("2/C", "To be renovated");
	buildings.Add(apartment);

	House house = new House();
	house.Address = "New Street";
	house.Description = "Large family home.";
	house.Owner = "Mr. Smith.";
	buildings.Add(house);

	TrainStation trainStation = new TrainStation();
	trainStation.Director = "Mr. Kovacs";
	trainStation.Location = "Budapest";
	trainStation.NumberOfPassangers = 100000;
	trainStation.NumberOfTrains = 100;
	buildings.Add(trainStation);

	foreach (IBuilding building in buildings)
	{
		building.Print(formatter);
	}
	Console.ReadKey();
}

Run the app and you’ll see that the properties of each object are printed out in the console.

Now if the customer wants new types of format then you can just say “ah, OK, give me five minutes!”. 5 minutes of programming can give you a fancy formatter such as this:

public class FancyFormatter : IFormatter
    {
        public string Format(string key, string value)
        {
            return string.Format("-=! {0} ----- !=- {1}", key, value);
        }
    }

Then just change the type of the formatter in the Main method to test the output. There you are, you have a new formatter without changing any of the domain objects. We change the formatting behaviour of each object without having to add extra parameters and inhering from existing classes to override the Print method. It’s now a breeze to add new types of formatters. The formatting behaviour is decoupled from the Print() method. We still print out each property of our objects but it is the formatter that takes care of formatting that printout. We can even apply a different formatter to each of our domain objects.

In the language of the pattern we have the following components:

  • IBuilding: the abstraction
  • Building types: the refined abstractions that implement the abstraction
  • IFormatter: the implementor which is the second level abstraction
  • Formatter types: the concrete implementors which implement the implementor abstraction

We’ve successfully abstracted away printing format mechanism and introduced a second level of abstraction required by the pattern. In fact we’re bridging the ability to print and the way the actual printing is carried out. You may not even want to print on the Console window but on a real printer. You can abstract away that logic using this pattern.

Let’s add yet another formatter:

public class UglyFormatter : IFormatter
{
	public string Format(string key, string value)
	{
		return string.Format("*^*_##@!!!!!!!&/(%&{0}:{1}", key, value);
	}
}

Again, change the formatter type in the Main method to see the effect. We can even have a menu list where the customer can pick the format.

Also, our formatters are proper objects, not primitives such as a boolean flag or an enumeration where we inspect the parameter in a long if-else statement.

We could even add other types of implementors, such as language formatters, colour formatters etc. to the Print method using this pattern. We can vary them as we wish: ugly formatting – English – red, fancy formatting – German – yellow.

Common usages of this pattern include:

  • Graphics: if you run a Java desktop application on Windows or a Mac then the GUI elements, such as the button, may be draw differently depending on the operating system
  • Persistence: database persistence, file persistence, memory persistence etc. where the object may have Persist method with an IPersistence interface taking care of the persistence logic
  • .NET providers: profiles and membership have their built-in providers in .NET that you may have used in your code. Those are also based on the bridge pattern: we bridge the ability to authorise a user and the actual way of performing the authorisation

In case you feel the need to build a large class hierarchy where the concrete classes only change some type of logic but are not truly different domain objects then you may have a candidate for the bridge pattern.

View the list of posts on Architecture and Patterns here.

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.

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.

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.

%d bloggers like this: