Architect or Cobbler?
Good code starts with good design

Factory Methods

Wednesday, September 07, 2005
In my last blog, I talked about Singletons. You used a static method to return an instance. This is actually an example of a type of pattern called the Factory Method, albeit a very specialised example. Quite simply, instead of allowing the user to directly create objects, you provide a static Factory Method that will return instances of the required type. You must make sure that the factory method returns either an interface or an abstract type, allowing you to easily add new types in the future. This gives you a factory class something like this:

using System;
using System.Configuration;
using SingerLibrary;

namespace Factory
{

    public class SingerFactory
    {
        public static Singer GetSinger() 
        {
           return null; //for now
        }
    }

}

namespace SingerLibrary
{
    
    public interface Singer
    {
        void Sing();
    }
}
  The SingerFactory determines what type of Singer to return (although you could provide arguments in the factory method that the client can pass in to provide some hints), and a useful place to keep the configuration items is in the application config file, as I've done here.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
      <add key="GreatSinger" value="SingerLibrary.Elvis" />
      <add key="DuffSinger" value="SingerLibrary.James" />
  </appSettings>
</configuration>
  The GetSinger method could now look up the key and use the value to create and instantiate a specific type of Singer, although having heard me sing, you wouldn't pay for the privilege again.

    public class SingerFactory
    {
        public static Singer GetSinger() 
        {
            // Normally you would have a better mechanism
            // than a random number generator, but it is only
            // an example
            if (new Random().Next(10)< 5) 
            {
                return GetSinger("GreatSinger");
            }
            else 
            {
                return GetSinger("DuffSinger");
            }

        }

        private static Singer GetSinger(string type) 
        {
            // No error handling in this method :-))
            // It's just an example, normally I say 
            // 'removed for clarity', hopefully you fall for it.

            string concreteType =  ConfigurationSettings.AppSettings.Get(type);
            string assembly = "SingerLibrary";
            return (Singer) Activator.CreateInstance(assembly,concreteType).Unwrap();
        }
   }
  Clearly Elvis and James are simply implementations of the interface Singer. This approach to object construction is rather simplistic however, and although factory methods are widely used, there has to be some better way of selecting the type of object you want returned. I couldn't imagine Simon Cowell wanting to use my SingerFactory, for instance. Another issue, of course is the proliferation of concrete instances which are very similar to each other (although James is not very similar to Elvis, except possibly in circumference - and I'm not talking the young Elvis' waistline). So in some future blog , I'll examine the Abstract Factory pattern. This won't be for a while though, as next week I'm at PDC - woo hoo. Dave will be there with me, along with Thomas Lee, QA's chief technologist. Along with them I will be reporting daily on the goings on at PDC - so if you can't make it there then have a read of the blog. And if you are a blog reader, and see me at PDC, you may even convince me to buy you a beer (more likely I'll try to get Dave to buy it though). PS ADO.NET 2.0 and ASP.NET 2.0 heavily rely on factories through the use of the Provider, so I might make a short detour through the Provider

# posted by James @ 2:06 PM   0 comments Comments: Post a Comment

<< Main blog page
This page is powered by Blogger. Isn't yours?