Tuesday 23 September 2008

Abstract Factory Pattern



Purpose:
The Abstract Factory Pattern involves the following OO priciple: Depend upon abstractions, do not depend upon concerete classes.

Abstraction doesn't necessarily mean an Interface. It points to a super type. It could easily be an Abstract class.

Encapsulating Object Creation. But Why?
We all have been "newing" for a long time without worries. Now we say that its better to encapsulate object creation. How is it going to help us? We are "newing" anyways!

The problem is certainly not with "new". Its the change that brings all the change. We need a way to encapsulate all the related "newing" at a single place so that its not spread across the code. In this example, a NuclearOrdananceFactory(Factory) is entrusted with creating Bullets, Guns, and Bombs(Products). Whenever Russia or China(Client) needs to create Nuclear bombs it goes to the Factory. It simply creates relevant weapons. No hassles, no worries, no code duplication, and no maintenance nightmares.

Abstract. Why Abstract?
The Factory classes like NuclearOrdnanceFactory, and BiologicalOrdnanaceFactory implement an Abstract interface. This allows the Client to create a set of related products.

I am presenting to you the most common design pattern that is also widely mis-understood! I am trying to simplify things by giving you a code sample and a test fixture that explains the usage.

It involves three distinct participants: The Factory, The Product, and The Client. The following class diagram will help ease down things.



The following fixture explains the usage of the factory.



/*
*
* Date Created: 16-Sep-2008
* Author: SAHAY, Sanjeet, IDC
* Filename: AbstractFactoryFixture.cs
* Assembly: Sanjeet.Demos
* Project: Demos
* Purpose: The Abstract Factory Pattern involves the following OO priciple:
* Depend upon abstractions, do not depend upon concerete classes
*
*/

using NUnit.Framework;
using Sanjeet.Demos.Patterns.AbstractFactory.Client;
using Sanjeet.Demos.Patterns.AbstractFactory.Factory;

namespace Sanjeet.Demos
{
[TestFixture]
public class AbstractFactoryFixture
{
[Test]
public void CreateABiologicalCountry()
{
IOrdnanceFactory factory = new BiologicalOrdnanceFactory();
ICountry country = new China();
country.MakeWeapon(factory);
}

[Test]
public void CreateAChemicalCountry()
{
IOrdnanceFactory factory = new ChemicalOrdnanceFactory();
ICountry country = new UnitedStates();
country.MakeWeapon(factory);
}

[Test]
public void CreateANuclearCountry()
{
IOrdnanceFactory factory = new NuclearOrdnanceFactory();
ICountry country = new India();
country.MakeWeapon(factory);
}

[Test]
public void CreateAStrongCountry()
{
ICountry country = new India();
country.MakeWeapon(new NuclearOrdnanceFactory());
country.MakeWeapon(new ChemicalOrdnanceFactory());
country.MakeWeapon(new BiologicalOrdnanceFactory());
}
}
}


Cheers!

No comments: