Home  /  Questions  /  Question



50   50
Sep 25, 2012


Facade with factory pattern

i am implementing a facade for my Business layer

currently i am having mulitple interfaces such as,
interface A
{
do();
}
interface B { undo(); }
and classes as
class A1 : A { void do() { //do } }
class B1 : B { void undo() { //undo } }

so to avoid these multiple interfaces i made a single class as
class facade { virtual void do(){} virtual void undo(){} }
 and classes as

class A1 : facade { override void do() { //do } }
class B1 : facade { override void undo() { //undo } }
after this there is factory to create object of facade.
class factory {
 public static Facade Create(ObjType type)     {         Facade obj = null;
        switch (ObjType)         {             case "A1":                 obj = new A1();                 break;             case "B1":                 obj = new B1();                 break;         }         return obj;     } }


So, my question is implementing facade as above is right way? or some other way it can be done better?
Thanks in advance
C# Business Tier factory facade
Flag
Follow
Email
 



1 answer
80   96.3
Sep 27, 2012
Hi,

In short:
Facade is not Creational Design pattern it is a structural Design pattern and available for its own purpose

Abstract Factory , provides kind of Facade for Creating products that belongs to its own factories (interfaces or abstract classes) . Please take a look at Abstract Factory UML diagram , you may get an idea.

in detail :

Not sure if you are using C#. In the code design above,
Virtual is being used , because that allows you NOT to Implement (in otherwords overridde) "Do" or "Undo" in Class A1 or B1. It implies Class A1 and Class B1 are separate products, and interfaces Interface A and Interface B appears to be individual factories providing an interface to create their own products.

Facade actually aggregates various entities and provide a single point to access those, agreed!.

But If you look at Abstract Factory it does similar , like providing interface to CreateProductA, CreateProductB etc., and far more better interface to create families of products.

For your understanding and convenience have merged both Facade and Abstract Factory and provided the code below (though deviating design patterns).

In the facade one , for instance if you Pass "B" and you could call ProductA.Do() that does not restrict you ...
In the abstract factory you deal with the respective families of products only.
To emphasis on families of products, have created A1, A2 , B1 , B2.

Hope this helps.

Happy Coding!
Tarriq Ferrose Khan


//.NET C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ConsoleApplication1
{

    public class MainTest
    {

        static void Main()
        {
            Console.WriteLine("....Abstract Factory....");
            AbstractFactory factory = new AbstractFactory();
            factory.CreateProductA("1").Do();
            factory.CreateProductA("2").Do();
            factory.CreateProductB("1").Undo();
            factory.CreateProductB("2").Undo();

            Console.WriteLine("....facade....");

            Facade facade = new Facade();
            facade.FacadeCreateProduct("A", "1").ProductA.Do();
            facade.FacadeCreateProduct("A", "2").ProductA.Do();
            facade.FacadeCreateProduct("B", "1").ProductB.Undo();
            facade.FacadeCreateProduct("B", "2").ProductB.Undo();
            Console.ReadLine();
        }

    }

    #region "Facade"

    public class Facade
    {
        private InterfaceA _ProductA;
        private InterfaceB _ProductB;

        public InterfaceB ProductB
        {
            get { return _ProductB; }
            set { _ProductB = value; }
        }

        public InterfaceA ProductA
        {
            get { return _ProductA; }
            set { _ProductA = value; }
        }

        public Facade FacadeCreateProduct(string strFactoryType, string strProductType)
        {
            switch (strFactoryType)
            {
                case "A":
                    ProductA = new AbstractFactory().CreateProductA(strProductType);
                    break;
                case "B":
                    ProductB = new AbstractFactory().CreateProductB(strProductType);
                    break;
            }
            return this;
        }

    }

    #endregion

    #region Factories

    public class FactoryA
    {
        InterfaceA interfaceA;
        public InterfaceA GetProduct(string strType) //for simplicity
        {
            switch (strType)
            {
                case "1":
                    interfaceA= new ClassA1();
                    break;
                case "2":
                    interfaceA= new ClassA2();
                    break;
            }
            return interfaceA;
        }
    }

    public class FactoryB
    {
        InterfaceB interfaceB;
        public InterfaceB GetProduct(string strType) //for simplicity
        {
            switch (strType)
            {
                case "1":
                    interfaceB = new ClassB1();
                    break;
                case "2":
                    interfaceB = new ClassB2();
                    break;
            }
            return interfaceB;
        }
    }

    public abstract class AbstractEntity
    {
        public abstract InterfaceA CreateProductA(string strType);
        public abstract InterfaceB CreateProductB(string strType);
    }

    public class AbstractFactory : AbstractEntity
    {

        public override InterfaceA CreateProductA(string strType)
        {
            InterfaceA interfaceA = new FactoryA().GetProduct(strType);
            return interfaceA;
        }

        public override InterfaceB CreateProductB(string strType)
        {
            InterfaceB interfaceB = new FactoryB().GetProduct(strType);
            return interfaceB; 
        }
       
    }

    #endregion 

    #region Interfaces

    public interface InterfaceA
    {
        void Do();
    }

    public interface InterfaceB
    {
        void Undo();
    }

    
    #endregion

    #region Products

    public class ClassA1 : InterfaceA
    {
        public void Do()
        {
            Console.WriteLine("Class A1: Do");
        }


    }

    public class ClassA2 : InterfaceA
    {
        public void Do()
        {
            Console.WriteLine("Class A2: Do");
        }


    }

    public class ClassB1 : InterfaceB
    {

        public void Undo()
        {
            Console.WriteLine("Class B1: Undo");
        }

    }

    public class ClassB2 : InterfaceB
    {

        public void Undo()
        {
            Console.WriteLine("Class B2: Undo");
        }

    }

    #endregion


}

 
 3 comments
 
Thanks for your detailed explanation. --- Suhas Patil  Sep 28, 2012
 
Actually what i want do is i have multiple service classes and want to provide a single interface to refer these class.So i thought to implement Facade for this. Your suggested solution is way big for this. So do you have any other suggestions for this requirement? thanks for your valuable inputs. --- Suhas Patil  Oct 15, 2012
 
Please refer to Entity Framework , Service locator pattern (though service locator is sometimes argued as anti-pattern, it suits for your situation well). Hope this helps. Thanks Tarriq --- Tarriq Ferrose Khan  Oct 16, 2012

 

Write Your Answer