Learn.Develop.Share

Twitter












Patterns: Abstract Factory

Intent

Provide interface for creating families of related or dependent classes without specifying there concrete classes.

Scenario:

I have been wondering about a valid scenario where I would put the Abstract Factory Into play. To be honest it took me some time to really find a valid scenario where I should use it. The catch is "creating families of related or dependent classes", and where would one need this. Where is it being used. We are currently working on development of a framework. Initially it used to have a Telerik controls based UI. And we also used the Ribbon Bar implementation on top of the telerik controls. What this did was made our pages heavy, in the rounds of ~2MB. This made us thinking, not everybody, would be happy to use it this way, so we thought of coming up with a light UI something that limits the page sizes considerabley. In the light UI, we are not using any ribbon controls, rather its a normal menu. Having said that, the solution that you are going to see is just not Abstract Factory only, so I would just omit out the other unrelevant in the context of the post. Apart from the above mentioned scenario, the other place it gets utilizied is ADO.Net. The idea is if you are using a SQL Data Provider then the Connection class should be of SqlConnection noly, like wise the SQLCommand class, the SQLDataAdapter class and so forth. But instead if you are connecting to a MySQL Database, then the connection class would be probably MySqlConnection class and like wise, MySqlCommand class and so forth. If you can notice a pattern, we are talking of creating a family of related products. Lets now look at the Abstract Factory:

What the Abstract factory says is,
  • You define Abstract classes for the related products- In our case, we will have AbstractButton, AbstractDropdown for the UI Problem and in case of ADO.Net we have IDBConnection interface and IDBCommand and etc.
  • Then you define a Abstract Factory for creating the different instances of your abstract products - In our case, we would have CreateButton, CreateDropdown etc. I am not aware if, ADO.Net does provide a factory class.
  • Then what we need is implement the Abstract classes and Abstract Factory for creation of the related products and each group of related products being reprsented by a Implementation of the Factory.
What you get out of it ?
  • You abstract the creation process of the components from the code and this allows you to replace it by some other implementation of the Abstract Product. Flexibility and loose coupling is what you gain.
  • Reusablilty of the same code that uses your Abstract Products.
 
Sample:
using System;


namespace Coderslog.Tryst.DesignPatterns
{
    //interface representing a Button
    public interface IButton
    {
        //Button Properties
    }

    public class SimpleButton : IButton
    {
    }
        
    public class RichButton : IButton
    {
    }

    //interface representing a TextBox
    public interface ITextBox
    {
        //TextBox Properties
    }

    public class SimpleTextBox : ITextBox
    {
    }
    
    public class RichTextBox : ITextBox
    {
    }

    //Abstract Factory interface for Creating UI Components
    public interface IUIComponentFactory
    {
        IButton GetButton();
        ITextBox GetTextBox();
    }

    //Factory Class for Creating Simple UI Components
    public class SimpleUIFactory : IUIComponentFactory
    {

        #region IUIComponentFactory Members

        public IButton GetButton()
        {
            return new SimpleButton();
        }

        public ITextBox GetTextBox()
        {
            return new SimpleTextBox();
        }

        #endregion
    }

    //Factory Class for Creating Rich UI Components
    public class RichUIFactory : IUIComponentFactory
    {
        #region IUIComponentFactory Members

        public IButton GetButton()
        {
            return new RichButton();
        }

        public ITextBox GetTextBox()
        {
            return new RichTextBox();
        }

        #endregion
    }


    ///Usage
    public class UIComponentFactory : IUIComponentFactory
    {

        private IUIComponentFactory _internalFactory;

        public UIComponentFactory()
        {
            _internalFactory = new RichUIFactory();
        }

        public UIComponentFactory(string config)
        {
            if (config == "Simple")
                _internalFactory = new SimpleUIFactory();
            else
                _internalFactory = new RichUIFactory();
        }

        #region IUIComponentFactory Members

        public IButton GetButton()
        {
            return _internalFactory.GetButton();                
        }

        public ITextBox GetTextBox()
        {
            return _internalFactory.GetTextBox();
        }

        #endregion
    }

}


Feedback

# re: Patterns: Abstract Factory

Excellent article abt the abstract factory pattern. 5/18/2010 2:58 PM | Vijay