DCSIMG
Abstract Factory Pattern - Gil Fink's Blog

Gil Fink's Blog

Fink about IT

News

Microsoft MVP

My Facebook Profile My Twitter Profile My Linkedin Profile

Locations of visitors to this page

Creative Commons License

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.
© Copyright 2012 Gil Fink

Hebrew Articles

Index Pages

My OSS Projects

English Articles

Abstract Factory Pattern

Abstract Factory Pattern

Today I'm going to write about one of the most popular patterns in the design
patterns
world - the abstract factory.
You can read my previous posts about design patterns here:
Structural patterns
Decorator pattern 
Proxy pattern
Facade pattern
Adapter pattern
Composite pattern
Bridge pattern
Flyweight pattern

Creational patterns
Singleton pattern

What is Abstract Factory Pattern
The abstract factory provides an interface for creating families of related
objects without concrete classes specifications.
The abstract factory dictates which products the concrete factories will produce.
Each concrete factory can build different products of different types.
The only way to get the products by the client is through the factory which isolate
the products definition and creation.
The benefits of using the pattern are the isolation of concrete classes, it makes it easy to
exchange product families and it makes the products consistent.
The drawback of the pattern is that the support of new products is difficult.
For a UML diagram of the pattern go to dofactory site.

C# Example
Lets look at an example of abstract factory use:

    #region Helper Enum

 

    enum eMaterialType

    {

        Wood,

        Iron

    }

 

    #endregion

 

    #region Abstarct Factory

 

    interface IFactory

    {

        #region Methods

 

        Table CreateTable();

        Door CreateDoor();

 

        #endregion

    }

 

    #endregion

 

    #region Concrete Factories

 

    /// Concrete factory for wood products

    class WoodFactory : IFactory

    {

        #region IFactory Members

 

        public Table CreateTable()

        {

            return new WoodTable();

        }

 

        public Door CreateDoor()

        {

            return new WoodDoor();

        }

 

        #endregion

    }

 

    // Concrete factory for iron products

    class IronFactory : IFactory

    {

        #region IFactory Members

 

        public Table CreateTable()

        {

            return new IronTable();  

        }

 

        public Door CreateDoor()

        {

            return new IronDoor();  

        }

 

        #endregion

    }

 

    #endregion

 

    #region Abstarct Products

 

    // The two products in the example

    // share the same material property

    interface IProduct

    {

        string Material { get; }

    }

 

    // Product A

    abstract class Table : IProduct

    {

        #region IProduct Members

 

        public string Material

        {

            get

            {

                return eMaterialType.Wood.ToString();

            }

        }

 

        #endregion

    }

 

    // Product B

    abstract class Door : IProduct

    {

        #region IProduct Members

 

        public string Material

        {

            get

            {

                return eMaterialType.Iron.ToString();

            }

        }

 

        #endregion

    }

 

    #endregion

 

    #region Concrete Products

 

    #region Wood Products

 

    class WoodTable : Table

    {

        // implement whatever you need

    }

 

    class WoodDoor : Door

    {

        // implement whatever you need

    }

 

    #endregion

 

    #region Iron Products

 

    class IronTable : Table

    {

        // implement whatever you need

    }

 

    class IronDoor : Door

    {

        // implement whatever you need

    }

 

    #endregion

 

    #endregion

The example is easy to understand.
I first created the IProduct interface because the products share the same property
(Material). Then, I created the abstract products of Door and Table.
For every material I created a relevant product (IronDoor, IronTable, WoodDoor and
WoodTable). After I created the products it was the time to create the factories.
I first create an interface (IFactory) which is the abstract factory.
The interface dictate that every concrete factory need to create doors and tables.
Next, I created the concrete factories which are the WoodFactory and the IronFactory.
Those factories will create the relevant product for every create method.

Summary
To sum up the post, use the pattern whenever you need that the application you build
should be independent of how the products are created or composed. Use it also when you
have families of related objects.
One thing you need to keep in mind. It's not easy to add new products to the factory.
Adding a new product to the factory requires changes in the concrete factories interface.
The client also need to change in order to use the new product.
The next pattern in the series will be the prototype pattern.

Comments

Traun Nigam said:

The code you provide is simple n easy to understand but could u give some real world example so that i can implement in my cureent railway.what u have given is simple but i m not able how i can implemnt please some situation related to rela world problem whic reduce the round trip using abstract factory.Hope I willget positive repsonse for your side.

thanx in advance with regs

Tarun Nigam

# July 16, 2008 10:41 AM

Gil Fink said:

Hi Traun Nigam

Sorry fo the late answer but I was very occupied this week with personal things. You can look at a real world example in the following link: www.dofactory.com/.../PatternAbstract.aspx

The example provide different animal worlds for a computer game using different factories. Hope it will help you. If not reply to the comment.

Gil

# July 24, 2008 3:47 PM

Anand said:

So how would the client look?

# January 28, 2009 10:13 AM

Gil Fink said:

@Anand,

A consuming code can look like:

IronFactory factory = new IronFactory();

Table newTable = factoy.CreateTable();

// do whatever you like with the new table which is an iron table

Simple as that.

# January 28, 2009 10:43 AM