Concept Of Factories In Object Oriented Programming

Factories

Types of Factories,

  • Simple Factory
  • Factory Method
  • Abstract Factory

Benefits

  • If multiple classes needs to be instantiated which have implemented same Interface
  • When we want to separate instantiation of object from its representation; i.e., we may have a setter and we have to call bunch of set methods on entity where we do not have access to property setter, we may want to wrap that inside factory.
  • Loss of if else or switch case deciding which class needs to insatiate.

Purpose

  • Separate object creation from decision of which object to create; i.e., whether I want BMW or any other, I need to specify without performing object instantiation within my class.
  • Add new classes and functionality without breaking OCP(Open close Principle) i.e. We want to add new IAuto that will be factory-produced objects or any time we want to add factories themselves e. we may have multiple factory types which we would like to add, which we will see in abstract factory.
  • State which object to create outside of programme

    • In database
    • In configuration

i.e. Many times we want to store object outside of programme i.e. I have database or in configuration.

Example

Simple Factory

  • Encapsulate Object Creation

Purpose of this factory is to encapsulate object creation away from main program which is executable. It allows for what type of class we are going to create based on configuration, and we can store at config file, we can store at other persistent mediums like database, or we can make those decision on the basis of input.

  • Allow for late bound decisions regarding instantiation

    • Config based
    • Other persistent storage
    • Input or dynamic database.

This particular factory is unique, caller class needs to know what concrete factory to call to do the instantiation

  • Caller class knows what concrete factory it needs

Example 

  1. class Program  
  2.   {  
  3.    
  4.     static void Main(string[] args)  
  5.     {  
  6.       
  7.     string carName= args[0];  
  8.     AutoFactory factory = new AutoFactory();  
  9.     IAuto car factory.CreateInstance(carName);  
  10.     car.TurnOn();  
  11.     car.TurnOff();  
  12.   }  
  13. }   

Now in this example we do not know which class will get instantiated, we only know we ae receiving instance of IAuto, which allows us to turn on and turn off.

Now explain Autofactory,cs

  1. public  class AutoFactory  
  2.   {  
  3.       Dictionary<string, Type> autos;  
  4.       public AutoFactory()  
  5.       {  
  6.           LoadTypesICanReturn();  
  7.       }  
  8.   
  9.       public IAuto CreateInstance(string carName)  
  10.       {  
  11.           Type t = GetTypetoCreate(carName);  
  12.           if (t == null)  
  13.               return new NullAuto();  
  14.   
  15.           return Activator.CreateInstance(t) as IAuto;  
  16.       }  
  17.   
  18.       private Type GetTypetoCreate(string carName)  
  19.       {  
  20.           foreach (var auto in autos)  
  21.               if (auto.Key.Contains(carName))  
  22.                   return autos[auto.Key];  
  23.           return null;  
  24.       }  
  25.   
  26.   
  27.       private void LoadTypesICanReturn()  
  28.       {  
  29.           autos = new Dictionary<string, Type>();  
  30.   
  31.           Type[] typesInThisAssembly = Assembly.GetExecutingAssembly().GetTypes();  
  32.           foreach (Type types in typesInThisAssembly)  
  33.           {  
  34.               autos.Add(types.Name.ToLower(), types);  
  35.           }  
  36.       }  
  37.   }   

Now in this program class knows concrete factory class and using that factory it will create instance of createAuto.

Factory Method

Define an interface for creating an object, but let the subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

Define an interface for classes which is responsible for creating object. Then let subclasses decide which class to instantiate; i.e. ,let the different factories that are here to factory interface decide which class they are going to instantiate.

Factory method lets a class defer instantiation to subclasses; i.e., we may have abstract base class factory at the highest level, and we are going to have derived classes. Those are concrete factory that provide us concrete classes back to our application.

The major point here is thatwe are going to the factory itself.

  • Defer object creating to one of many factories that have an interface
    As before we had one factory for all types of cars, now we can have factories that are specialized in their particular Automobiles.
  • Derived class implement or override the factory method of the base.
    To achieve this functionality simply by overriding factory method which is defined on base class or Interface.

    Factories

In this class diagram, we can see that we have base client programm, which we had before that is going to load given factory using IAutofactory

And based on one of the factories we have in our project, whether you can have minicooperFactory concrete factory or BMWFactory concrete factory. One of those concrete factories is inheriting to IAutofacorty which provides definition for CreateAutomobiles method that returns IAuto.

That means this minicooperfactory is going to know how to create Minicoopers & the BMWFactory is going to know how to create BMWs.

Each Factory will do whatever concrete classesneed;  i.e., MiniCooper or BMW.

And BMW, MiniCooper will implement IAuto interface which gets returned to client from factory interface.

Example 

  1. public interface IAutofactory  
  2. {  
  3.       IAuto CreateAutomobile();  
  4. }   

IAutofactory

  1.     class  Program  
  2.   
  3.  IAutoFactory autoFactory = LoadFactory();  
  4.       IAuto car = autoFactory.CreateAutomobile();  
  5.       car .TurnOn();  
  6.       car .TurnOff();  
  7.         }  
  8.     static  IAutoFactory LoadFactory()  
  9.      {  
  10.            string factoryName= Properties.Settings.Default.AutoFactory;  
  11.            return Assembly.GetExecutingAssembly().CreateInstance(factoryName) as IAutoFactory;       
  12.      }  
  13. }   

We call create Automobile(), this factory knows how to create MiniCooper & calls SetName. Now this is one type of call that might need to be made on a class or entity to set up properly, that we do not want people to guess in case of building their application. That’s why we have factory so that we can centralize the logic decision. When you create mini you need to call SetName on that class in order to set up that class properly, so that is what we have done & we are returning mini. 

  1. public interface IAuto  
  2. {  
  3.   string Name{get;}  
  4.   void SetName(string name);  
  5.   void TurnOn();  
  6.   void TurnOff();  
  7. }   

Now if we look into BMW class, this concrete class implements the IAuto interface but implements some more functionality including a non-default constructor that takes a name so that it does not require calling SetName.

This is a good example, here we have two different concrete classes, both of which implement the same interface; however, each needs their own specific construction. 

  1. public interface IAuto  
  2. {  
  3.    string Name{get;}  
  4.    string SetName{string name;}  
  5.    void TurnOn();  
  6.    void TurnOff();  
  7. }   

Abstract Factory

Provides an interface for creating families of related or dependant objects without specifying their concrete classes.

Here we are going one step deeper by adding bit more complexity with abstract factory and this pattern as described, provides an interface just like we saw with factory method, but in this case our factories will know how to create different types of products, those may not just return one product type, they may in fact know how to create different types of products based on some input parameters to the factory method or by some other means like factory that is responsible for creating database connection. We may have one factory for Oledb, one for Sql Server and another for Oracle connection. Each one of those factories may know how to create different types of connections based on input parameter is been given to create the connection.

Now in our example we will have BMWFactory that knows how to create different types of BMW cars.

Therefore there are major features of abstract factory pattern is provided below

  • Factory creates different types of concrete objects(products)
  • A Factory now represents a “Family” of object that it can create.
  • Factories that may have more than one factory method.

    Factories

In Class Diagram

Here is class model for abstract factory. We can see we have IAutofactory interact with CreateEconomyCar(), CreateLuxuryCar() and CreateSportsCar() abstract methods, however we can go for only one abstract method with paramaeter also.

Now we have MiniCooperFactory and MNWFactory which is implementing IAutoFactory, these are concrete classes that know how to create Automobiles.

And we Have IAutomobiles; we are working with the same interface so far, and we can simply turnOn and turnoff.

And BMWFactory is going to know how to create BMW vehicles and MiniCooperFactory is going to know how to create MiniCooperVehicles.

Now an example,

Here on entry point for our abstract factory implementation, we load our factory by LoadFactory(). This is exactly how we loaded our factory last time.

Now in this we have separate different cars that are going to be created.

We are going to create separate classes and turn them on and off.

Let’s go ahead and run our application and see.

Now, IAutofactory

It has three methods, however we could do this by creating one method; i.e. ,IAutomobile CreateCar(object parameter) & let the factory decide which type of car.

However we have not implemented in this way.

Now let’s look how MiniCooperFactory implements this.

Looks like we have only one object we are working with; i.e., MiniCooper in CreateSportsCar(), CreateEconomyCar() and CreateLuxuryCar(). And we are creating interface of MIniCooper cars.

And the difference in IAutomobile  being retuned is simply that factory knows to call certain methods that tweak the option of MiniCooper before it returns it backs adding luxury Package and Sport Package.

That’s a little bit different from how BMWFactory chooses and if you create a sports car you are going to get BMW3.

If you create Luxury you are going to get BMW740i & BMW228i () for Economy Car. And that means if we look into autos we have different types here i.e. MBW328, MBW740, etc. and they all share a base class.

And under MiniCooper, we are still using factory that responds to the need to create the sports car, luxury car and economy car based on the configuration of the minicooper create class.

Now run the code.

Consequences

A Few Notes about Abstract Factory,

  • Add new factories and classes without breaking OCP
    With the factory method we can add new factory in the classes (concrete classes) then factories return without breaking the Open Close Principle
  • Differ choosing classes to classes that specialize in making that decision.
    Again we get to defer the decision about what classes get created to the factories themselves and localize all of the construction logic within those factories.
  • Using private or internal constructors hides direction construction with new keyword
    And when we know that we can now use private even internal constructors where the factory in the concrete class are in the same assembly. When we do this we put internal or private classes on those concreate classes at the factories return. We can absolutely guard against knowing the objects by some means other than factory.

X

Build smarter apps with Machine Learning, Bots, Cognitive Services - Start free.

Start Learning Now