Tuesday, November 12, 2013

Abstract Factory Design Pattern

Hello

Abstract Factory  Design Pattern is largest pattern from 3 factory-family patterns:

1. Simple Factory
2. Abstract Factory
3. Factory Method

I will start from implementation, using, class diagrams. After, i will put points, make comparing to other patterns in family.

Code

As implementation i use example: building Suzuki liana and Peugeot 206 by using Abstract Factory  Design Pattern:
namespace AbstractFactoryDP
{
    #region Interfaces

    public interface IEngine
    {
        int GetHorsePower();
        double GetVolume();
    }

    public interface IWheel
    {
        int GetTireWidth();
        int GetAspectRatio();
    }

    public interface IAbstractCarsFactory
    {
        IEngine FactoryEngine();
        IWheel FactoryWheel();
    }
    #endregion

    #region Implementations
    public class Michelin : IWheel
    {
        public int GetTireWidth() { return 185; }
        public int GetAspectRatio() { return 55; }
    }

    public class GoodYear : IWheel
    {
        public int GetTireWidth() { return 185; }
        public int GetAspectRatio() { return 65; }
    }

    public class M16A : IEngine
    {
        public int GetHorsePower() { return 105; }
        public double GetVolume() { return 1.6; }
    }

    public class EW10J4S : IEngine
    {
        public int GetHorsePower() { return 175; }
        public double GetVolume() { return 2.0; }
    }

    public class Peugeot206CC : IAbstractCarsFactory
    {
        public IEngine FactoryEngine() { return new EW10J4S(); }
        public IWheel FactoryWheel() { return new Michelin(); }
    }

    public class SuzukiLiana : IAbstractCarsFactory
    {
        public IEngine FactoryEngine() { return new M16A(); }
        public IWheel FactoryWheel() { return new GoodYear(); }
    }

    #endregion
}

Using by client (as UnitTest):
IAbstractCarsFactory liana = new SuzukiLiana();
IAbstractCarsFactory peugeot = new Peugeot206CC();

IEngine lianaEngine = liana.FactoryEngine();
IEngine ccEngine = peugeot.FactoryEngine();

IWheel lianaWheel = liana.FactoryWheel();
IWheel ccWheel = peugeot.FactoryWheel();

Assert.AreEqual(lianaEngine.GetHorsePower(), 105, 0.01);
Assert.AreEqual(lianaEngine.GetVolume(), 1.6, 0.01);
Assert.AreEqual(ccEngine.GetHorsePower(), 175, 0.01);
Assert.AreEqual(ccEngine.GetVolume(), 2.0, 0.01);

Assert.AreEqual(lianaWheel.GetAspectRatio(), 65, 0.01);
Assert.AreEqual(lianaWheel.GetTireWidth(), 185, 0.01);
Assert.AreEqual(ccWheel.GetAspectRatio(), 55, 0.01);
Assert.AreEqual(ccWheel.GetTireWidth(), 185, 0.01);

Class Diagrams
Fig 1:class diagram without associations

Fig 2: class diagram with client associations

Fig 3: class diagram with associations inside of Abstract Factory

So, Abstract Factory, as other factories is creational pattern.
Main difference from Factory Method - is ability to create factory which can create many objects. In Factory Method there is single creator which can create object, but in Abstract Family can be a lot of creators, each can create specific object.
If we will redesign Abstract Factory abstract class to have only one creator, it will be looks, like a Factory Method. I just removed Engines from design. Described in Fig 4:

Fig 4:redesign to Factory Method

That's all
en → ru
объект
имя существительное: объект, предмет, цель, вещь, дополнение, несуразный человек, нелепая вещь
глагол: возражать, возразить, протестовать, не одобрять, не любить, не переносить
имя прилагательное: объектный, целевой, выходной

No comments:

Post a Comment