Factory Method Design Pattern

The factory method pattern is a design pattern that allows for the creations of objects without specifying the type of object that is to be created in code. A factory class contain a method that allow determination of the created type at run-time. It is used to replace class constructors, abstracting the process of object generation so that the type of the object instantiated can be determined at run-time.

One example of the use of the factory method pattern is when creating a connection to a data source if the type of the data source will be selected by the end-user using a graphical interface. In this case, an abstract class name “DataSource” may be created that defines the base functionality of all data source. Many concreate subclass may be created, perhaps “SqlDataSource”, “XmlDataSource”, “CsvDataSource”, etc, each with specific functionality for a differenct type of data. At run-time, a further class, perhaps named “DataSourceFactory”, generates objects of the correct class based upon a parameter passed to the factory method.

Implementation

Factory Method

The UML class diagram above describes an implementation of the factory method design pattern. In this diagram there are four classes:

  • FactoryBase: This is an abstract base class for the concrete factory classes that will actually generate new objects. This class could be a simple interface containing the signature for the factory method. However, generally an abstract class will be used so that other standard functionality can included and inherited by subclass. In simple situations the factory method may be implemented in full here. rather than being declared as abstract.
  • ConcreateFactory: Inheriting from the FactoryBase class, the concreate factory classes inherit the actual factory method. This is overridden with the object generation code unless already implemented in full in the base class.
  • ProductBase: This abstract class is the base class for the types of object that the factory can create. It is also the return type for the factory method. Again, this can be a simple interface info general functionality is to be inherited by its subclasses.
  • ConcreateProduct: Multiple subclasses of the Product class are defined, each containing specific functionality. Object of these classes are generated by the factory method.

The basic code of the factory method design pattern implemented using C# is shown in the following:

public abstract class FactoryBase
{
    public abstract Product FactoryMethod(int type);
}

public class ConcreteFactory : FactoryBase
{
    public override Product FactoryMethod(int type)
    {
        switch (type)
        {
            case 1:
                return new ConcreteProduct1();

            case 2:
                return new ConcreteProduct2();

            default:
                throw new ArgumentException("Invalid type.", "type");
        }
    }
}

public abstract class ProductBase { }

public class ConcreteProduct1 : ProductBase { }

public class ConcreteProduct2 : ProductBase { }

Example in C#

Example 1

This is a simple example of the factory method design pattern in action, The factory method GetPhone() will generate Phone object

namespace FactoryMethod
{
    public interface IPhone
    {
        decimal Price { get; }
    }

    public class Nokia : IPhone
    {
        public decimal Price
        {
            get { return 200; }
        }
    }

    public class Motorola : IPhone
    {
        public decimal Price
        {
            get { return 100; }
        }
    }

    public class PhoneFactory
    {
        public IPhone GetPhone(string type)
        {
            switch (type)
            {
                case "Nokia":
                    return new Nokia();
                case "Motorola":
                    return new Motorola();
                default:
                    return null;
            }
        }
    }
}

You just call GetPhone() and pass type as a parameter in your client code you will get a new Phone object

using System;
using FactoryMethod;

namespace FactoryMethod
{
    class Program
    {
        static void Main(string[] args)
        {
            PhoneFactory phoneFactory = new PhoneFactory();
            IPhone phone;

            phone = phoneFactory.GetPhone("Nokia");
            Console.WriteLine("The price for Nokia: {0}", phone.Price);

            phone = phoneFactory.GetPhone("Motorola");
            Console.WriteLine("The price for Motorola: {0}", phone.Price);

            Console.Read();
        }
    }
}

Example 2

This example is similar to the example 1. CreateConnection() will create connection object.

namespace FactoryMethod
{
    public interface IConnectionProvider
    {
        string ConnectionString { get; }
    }

    public class SqlServerConnection : IConnectionProvider
    {
        public string ConnectionString
        {
            get { return "Server=(local);initial catalog=AdventureWorks;Integrated Security=SSPI"; }
        }
    }

    public class OracleConnection : IConnectionProvider
    {
        public string ConnectionString
        {
            get { return "User ID=vorleak;Password=vorleak;Data Source=localhost"; }
        }
    }

    public class MySqlConnection : IConnectionProvider
    {
        public string ConnectionString
        {
            get { return "Database=AdventureWorks;Data Source=192.168.0.1;User Id=vorleak;Password=vorleak"; }
        }
    }

    public class ConnectionProviderFactory
    {
        public IConnectionProvider CreateConnection(string type)
        {
            switch (type)
            {
                case "SQL Server" :
                    return new SqlServerConnection();
                case "Oracle" :
                    return new OracleConnection();
                case "MySQL":
                    return new MySqlConnection();
                default:
                    return null;
            }
        }
    }
}

You don’t need to have condition in the client code just pass parameter type.

using System;
using FactoryMethod;

namespace FactoryMethod
{
    class Program
    {
        static void Main(string[] args)
        {
            ConnectionProviderFactory connectionProviderFactory = new ConnectionProviderFactory();
            IConnectionProvider connectionProvider;

            connectionProvider = connectionProviderFactory.CreateConnection("SQL Server");
            Console.WriteLine("ConnectionString for SQL Server: {0}", connectionProvider.ConnectionString);

            connectionProvider = connectionProviderFactory.CreateConnection("Oracle");
            Console.WriteLine("ConnectionString for Oracle: {0}", connectionProvider.ConnectionString);

            connectionProvider = connectionProviderFactory.CreateConnection("MySQL");
            Console.WriteLine("ConnectionString for MySQL: {0}", connectionProvider.ConnectionString);

            Console.Read();
        }
    }
}

4 people have left comments

Yusuf - Gravatar

Yusuf said:

Thank you very much for the simplicity of the article,
here I have found the information so simple and well designed for all the people to understand,
Regards from Türkiye

Posted on: October 26, 2008 at 2:14 pmQuote this Comment
chornsokun - Gravatar

chornsokun said:

excellent ;)

Posted on: October 29, 2008 at 10:55 amQuote this Comment
priyanka - Gravatar

priyanka said:

Hi, this example is great. could you please extend the same example and tell about abstract factory.

Thanks

Posted on: November 19, 2008 at 11:38 pmQuote this Comment
Ankit Verma - Gravatar

Ankit Verma said:

This code snippet is mind boggling surely as beginner to design pattern this blog is really a great help for me waiting for abstract factory sample too.

Posted on: November 20, 2008 at 11:42 amQuote this Comment

Leave a Comment-

Comment Guidelines: Basic XHTML is allowed (a href, strong, em, code). All line breaks and paragraphs are automatically generated. Off-topic or inappropriate comments will be edited or deleted. Email addresses will never be published. Keep it PG-13 people!

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

All fields marked with "*" are required.