Creational - Abstract factory Pattern

In continuation to my previous post, I am presenting you a sample code that implements Abstract Factory Pattern.

The overview:
 - This implementation contains a factory called Person.
 - The Product/Entity class is represented by 2 abstract classes called Gift and Letter.
 - The client class is called Client.
 - Employee and Colleague inherits from Person.
 - Email inherits Letter and Flowers inherit Gift.
 - Client creates/receives an instance of Person class which creates objects for Gift and Letter.

Takeaways:
 - As discussed earlier, Creational Patterns focus on creating objects of Product.
 - The complexity of this pattern increases as the number of Product increases. You have to add more virtual functions at the Person(Factory) level. Then override those functions at the Concrete classes of the Factory(eg., Employee, Colleague)

The Person class(Factory), this implementation uses the Singleton pattern with Lazy Initialization to make sure that there is only 1 instance in the application.

    1: public class Person
    2:     {
    3:         /// <summary>
    4:         /// Static variable of the class to see if its already instantiated
    5:         /// </summary>
    6:         private static Person _p;      
    7:  
    8:         /// <summary>
    9:         /// The virual functions to create a Gift Product
   10:         /// </summary>
   11:         /// <returns></returns>
   12:         public virtual Gift CreateGift()
   13:         {
   14:             return new Flowers();
   15:         }
   16:         
   17:         /// <summary>
   18:         /// The virual functions to create a Letter Product
   19:         /// </summary>
   20:         /// <returns></returns>
   21:         public virtual Letter CreateLetter()
   22:         {
   23:             return new Email();
   24:         }
   25:         
   26:         /// <summary>
   27:         /// This static method gets you the single instance of this class
   28:         /// </summary>
   29:         /// <returns></returns>
   30:         public static Person GetInstance()
   31:         {
   32:             if (_p == null)
   33:             {
   34:                 _p = new Person();
   35:             }
   36:             return _p;
   37:         }
   38:         
   39:         /// <summary>
   40:         /// Constructor with restricted access
   41:         /// </summary>
   42:         protected Person(){
   43:         }        
   44:     }

The Employee Concrete Class:

    1: /// <summary>
    2:     /// This is one of the Concrete classes which isolated from the client
    3:     /// </summary>
    4:     public class Employee: Person
    5:     {
    6:         /// <summary>
    7:         /// Constructor to the class
    8:         /// </summary>
    9:         public Employee():base()
   10:         {
   11:             
   12:         }
   13:  
   14:         /// <summary>
   15:         /// Override the virtual declared in the base class.
   16:         /// This function creates and returns one of the products - Flowers
   17:         /// </summary>
   18:         /// <returns></returns>
   19:         public override Gift CreateGift()
   20:         {
   21:             return new Flowers();
   22:         }
   23:  
   24:         /// <summary>
   25:         /// Override the virtual declared in the base class.
   26:         /// This function creates and returns one of the products - Email
   27:         /// </summary>
   28:         /// <returns></returns>
   29:         public override Letter CreateLetter()
   30:         {
   31:             return new Email();
   32:         }
   33:     }

The Colleague Concrete Class:

    1: /// <summary>
    2:     /// This is one of the Concrete classes which isolated from the client
    3:     /// </summary>
    4:     public class Colleague: Person
    5:     {
    6:         /// <summary>
    7:         /// Constructor to the class
    8:         /// </summary>
    9:         public Colleague():base()
   10:         {
   11:         }
   12:  
   13:         /// <summary>
   14:         /// Override the virtual declared in the base class.
   15:         /// This function creates and returns one of the products - Flowers
   16:         /// </summary>
   17:         /// <returns></returns>
   18:         public override Gift CreateGift()
   19:         {
   20:             return new Flowers();
   21:         }
   22:  
   23:         /// <summary>
   24:         /// Override the virtual declared in the base class.
   25:         /// This function creates and returns one of the products - Email
   26:         /// </summary>
   27:         /// <returns></returns>
   28:         public override Letter CreateLetter()
   29:         {
   30:             return new Email();
   31:         }
   32:     }

The Gift and Letter Abstract Product Classes:

    1: /// <summary>
    2:     /// This is the Product type #1
    3:     /// </summary>
    4:     public abstract class Gift
    5:     { 
    6:         protected string _name;
    7:         
    8:         public virtual string Name
    9:         {
   10:             get;set;
   11:         }
   12:              
   13:         public Gift()
   14:         {
   15:             _name = "Gift Constructor";        
   16:         }        
   17:     } 
   18:  
   19: /// <summary>
   20:     /// This is the Product type #2
   21:     /// </summary>
   22:     public abstract class Letter
   23:     {
   24:         protected string _purpose;
   25:                 
   26:         public Letter()
   27:         {
   28:             _purpose = "Letter Constructor";
   29:         }
   30:  
   31:         public virtual string Purpose
   32:         {
   33:             get;
   34:             set;
   35:         }
   36:     }

The Products - Email and Flowers:

    1: /// <summary>
    2:     /// This is product #1 of product type #1
    3:     /// </summary>
    4:     public class Flowers: Gift
    5:     {
    6:         public Flowers()
    7:         {
    8:             _name = "Flowers Constructor";
    9:         }
   10:         
   11:         public override string Name
   12:         {
   13:             get
   14:             {
   15:                 return _name;
   16:             }
   17:             set
   18:             {
   19:                 _name = value;
   20:             }
   21:         }      
   22:     }
   23:  
   24: /// <summary>
   25:     /// This is product #1 of product type #2
   26:     /// </summary>
   27:     public class Email: Letter
   28:     {
   29:     
   30:         public Email()
   31:         {
   32:             _purpose = "Email Constructor";
   33:         }
   34:         public override string Purpose
   35:         {
   36:             get
   37:             {
   38:                 return _purpose;
   39:             }
   40:             set
   41:             {
   42:                 _purpose = value;
   43:             }
   44:         }
   45:     }

 

Please write to me if you have any questions/suggestions.