CSC/ECE 517 Fall 2009/wiki3 6 Factory Design Pattern

From Expertiza_Wiki
Jump to navigation Jump to search

"Factory method is a type of creational pattern. Like other creational patterns, it deals with the problem of creating objects (products) without specifying the exact class of object that will be created. Be sure to emphasize how it is different from the more general Creator pattern. Also give several examples of how it can be used, and where it provides a more elegant solution than other creational patterns."

Introduction to Design Patterns

"Don't reinvent the wheel" all of us have heard this saying and "Design Patterns" is the software engineer's way of saying the same thing. In software engineering, a design pattern is a general reusable solution to a commonly occurring problem in software design. The credit for introduction and formalization of these reusable solutions goes to the "Gang of Four"(Gamma, Erich; Richard Helm, Ralph Johnson, and John Vlissides)[1]. A design pattern is not a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that can be used in many different situations. Object-oriented design patterns typically show relationships and interactions between classes or objects, without specifying the final application classes or objects that are involved.

Classification

Design patterns were originally grouped into the categories Creational patterns, Structural patterns, and Behavioral patterns. Another classification has also introduced the notion of architectural design pattern that may be applied at the architecture level of the software such as the Model-View-Controller pattern.For a complete list go to [2]

Creational pattern

In software engineering, creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or added complexity to the design. Creational design patterns solve this problem by somehow controlling this object creation.

Structural pattern

In software engineering, structural design patterns are design patterns that ease the design by identifying a simple way to realize relationships between entities.

Behavioral pattern

In software engineering, behavioral design patterns are design patterns that identify common communication patterns between objects and realize these patterns. By doing so, these patterns increase flexibility in carrying out this communication.

Architectural pattern

Architectural pattern are software patterns that offer well-established solutions to architectural problems in software engineering. It gives description of the elements and relation type together with a set of constraints on how they may be used. An architectural pattern expresses a fundamental structural organization schema for a software system, which consists of subsystems, their responsibilities and interrelations.

Creational patterns

In software engineering creational patterns are used to create objects suitable to the situation. In object oriented design object creation may lead to design problems if they are not controlled according to situations. Creational patterns deals with this mechanism. There are a list of different creational patterns available which solves problem of creating objects in different situations. The list includes factory design pattern as well. Here we'll see how factory design pattern is different from other creational design patterns and where it is mostly used.


Types of Creational Pattern

Factory method pattern

In object oriented design a factory is a place used for creating objects. Factory pattern provides centralize creation of an object of a specific type choosing one of several implementations. It encapsulates the creation of objects. At run time the decision is made about which object to instantiate depending on the situation. So it creates objects without specifying the class of the objects.

Abstract factory pattern

Abstract factories centralize the decision of which factory to instantiate. It provides an encapsulation to a group of factories that have common properties. The clients who implement abstract factories doesn't know which concrete object it gets from individual internal factories. The clients only implements the generic interface of these factories. To understand how this pattern is used refer to Abstract factory. This abstraction hides the details of different implementation of objects from their general usage. Factory design pattern is used inherently in this pattern design.

Prototype pattern

Prototype means making clones. This pattern is used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects. The cost of creating new objects is resource intensive job. This pattern gives solution in this scenario where object cloning saves this cost in terms of resources. This pattern is used to avoid building a class hierarchy of factories that parallels the class hierarchy of products. For a detailed understanding of this pattern refer to Prototype pattern.

Builder pattern

It is a creational pattern which abstracts the object creation pattern. Builder pattern separates the construction of a complex object from its representation so that the same construction process can create different representations. For a detailed understanding of this pattern refer to Builder pattern. This is much more complex object creation pattern than factory method. There may be cases where design starts with factory method and eventually leads to builder pattern according to the flexibility needed in object creation process.

Singleton pattern

This pattern restricts instantiation of the class to exactly one object. There may be situations where exactly one object of the class is needed. For example server configuration, logger etc where this pattern is used. Other design patterns like builder, prototype or abstract patterns can also use singleton pattern in their implementation. For a detailed understanding of this pattern refer to Singleton pattern.

Object pool

In object oriented design object creation and destruction after completing all operations on it is an expensive task. For example socket connection, database connection etc. are repetitive tasks but are resource intensive in terms of time. This pattern avoids this expensive acquisition and release of resources by by maintaining an object pool. The clients of the object pool places request when it needs an object and releases the hold on the object after performing desired tasks. Then the released objects are returned back to the object pool for reuse. Objects in object pool are specific type of factory object. It can be used for creating singleton object also.

Lazy initialization pattern

This pattern deals with the mechanism of delaying the creation of an object until the first time the object is needed. The delay in object creation may be required depending on the situations like the calculation of a value or some other expensive process. This pattern can be used together with factory design pattern to design "lazy factory". To understand how 'lazy factory' works refer to lazy initialization.

Factory Method Pattern

What is factory method?

In object oriented language, factory method pattern is a creational design pattern which deals with the mechanism of creating objects of the classes without specifying the exact class of the object. The Factory Method pattern is a lightweight pattern that achieves independence from application-specific classes. The client programs to the interface and lets the pattern sort out the rest 6

Motivation

Also known as Virtual Constructor, the Factory Method is related to the idea on which libraries work: a library uses abstract classes for defining and maintaining relations between objects. One type of responsibility is creating such objects. The library knows when an object needs to be created, but not what kind of object it should create, this being specific to the application using the library.

The Factory method works just the same way: it defines an interface for creating an object, but leaves the choice of its type to the subclasses, creation being deferred at run-time. A simple real life example of the Factory Method is the hotel. When staying in a hotel you first have to check in. The person working at the front desk will give you a key to your room after you've paid for the room you want and this way he can be looked at as a “room” factory. While staying at the hotel, you might need to make a phone call, so you call the front desk and the person there will connect you with the number you need, becoming a “phone-call” factory, because he controls the access to calls, too.

Intent

  • It defines an interface for creating objects, but let subclasses to decide which class to instantiate
  • It refers to the newly created object through a common interface

Implementation

The participants classes in this pattern are:

  • Creator(also refered as Factory because it creates the Product objects) declares the method FactoryMethod, which returns a Product object. May call the generating method for creating Product objects.
  • Product defines the interface for objects the factory method creates.
  • ConcreteProduct implements the Product interface.
  • ConcreteCreator overrides the generating method for creating ConcreteProduct objects



All concrete products are subclasses of the Product class, so all of them have the same basic implementation, at some extent. The Creator class specifies all standard and generic behavior of the products and when a new product is needed, it sends the creation details that are supplied by the client to the ConcreteCreator. Following is the code to explain this.

   public interface Product { … }
   public abstract class Creator 
   {	
       public void anOperation() 
       {   
           Product product = factoryMethod();
       }
       protected abstract Product factoryMethod();
   }
   public class ConcreteProduct implements Product { … }
   public class ConcreteCreator extends Creator 
   {   
       protected Product factoryMethod() 
       {
           return new ConcreteProduct();
       }
   }
   public class Client 
   {
       public static void main( String arg[] ) 
       {
            Creator creator = new ConcreteCreator();
            creator.anOperation();
       }
   }

When to use Factory Method?

The Factory patterns can be used in following situations:

  • When flexibility is important.
  • When a class does not know which class of objects it is going to create.
  • When a class gives the freedom to its subclasses to specify which objects to create.
  • Programmers use factory pattern where they have to create an object of any one of sub-classes depending on the data provided. The information about which class object is to create is not known to programmers beforehand and the decision is made at run time depending on the data provided.
  • When there is a specific reason why one subclass would be chosen over another. Basically this logic forms part of the Factory Method.
  • When the clients delegates responsibilities to subclasses in parallel hierarchies 6.
  • In test driven environment for the classes to be put under test3.

Example using Documents Application

Take into consideration a framework for desktop applications. Such applications are meant to work with documents. A framework for desktop applications contains definitions for operations such as opening, creating and saving a document. The basic classes are abstract ones, named Application and Document, their clients having to create subclasses from them in order to define their own applications. For generating a drawing application, for example, they need to define the DrawingApplication and DrawingDocument classes. The Application class has the task of managing the documents, taking action at the request of the client (for example, when the user selects the open or save command form the menu).

Because the Document class that needs to be instantiated is specific to the application, the Application class does not know it in advance, so it doesn't know what to instantiate, but it does know when to instantiate it. The framework needs to instantiate a certain class, but it only knows abstract classes that can't be instantiated.

The Factory Method design pattern solves the problem by putting all the information related to the class that needs to be instantiated into an object and using them outside the framework, as you can see below In the Application class the CreateDocument method either has a default implementation or it doesn't have any implementation at all, this operation being redefined in the MyApplication subclass so that it creates a MyDocument object and returns a reference to it.

 public Document CreateDocument(String type)
 {
       if (type.isEqual("html"))
               return new HtmlDocument();
       if (type.isEqual("proprietary "))
               return new MyDocument();
       if (type.isEqual("pdf"))
               return new PdfDocument();
 }	


Assuming that the Application class has a member called docs that represents a list of documents being handled by the application, then the NewDocument method should look like this:

   public void NewDocument(String type)
   {
       Document doc=CreateDocument(type);
       Docs.add(doc);
       Doc.Open();
   }

This method will be inherited by the MyApplication class and, so, through the CreateDocument method, it will actually instantiate MyDocument objects. We will call the CreateDocument method a Factory Method because it is responsible with 'making' an object. Through this method, redefined in Application's subclasses, we can actually shape the situation in which the Application class creates objects without knowing their type.

Other Examples of Factory pattern

Factory method in Java
abstract class Coffee {
   public abstract double getPrice();
}
class MochaCoffee extends Coffee {
   public double getPrice() {
       return 2.65;
   }
}
class CafeLate extends Coffee {
   public double getPrice() {
       return 2.10;
   }
}
class DarkRoastCoffee extends Coffee {
   public double getPrice() {
       return 1.96;
   }
}
class CoffeeFactory {
   public enum CoffeeType {
       Mocha,
       CafeLate,
       DarkRoast
   }
   public static Coffee createCoffee(CoffeeType coffeeType) {
       switch (coffeeType) {
           case Mocha:
               return new MochaCoffee();
           case CafeLate:
               return new CafeLate();
           case DarkRoast:
               return new DarkRoastCoffee();
       }
       throw new IllegalArgumentException(coffeeType + " is not an expected coffee type. This " + coffeeType + " is not served.");
   }
}
class coffeeLover {
   /*
    * Create all available coffees in the coffeeshop and print their prices
    */
   public static void main (String args[]) {
       for (CoffeeFactory.CoffeeType coffeeType : CoffeeFactory.CoffeeType.values()) {
           System.out.println("Price of " + coffeeType + " is " + CoffeeFactory.createCoffee(coffeeType).getPrice());
       }
   }
}
Factory method in Python
#: 
# A simple static factory method.
from __future__ import generators
import random
##
class Coffee(object):
 # Create based on class name:
 def factory(type):
   #return eval(type + "()")
   if type == "CafeMocha": return CafeMocha()
   if type == "CafeLate": return CafeLate()
   assert 1, "We don't serve this coffee: " + type
 factory = staticmethod(factory)
##
class CafeMocha(Coffee):
 def dark(self): print "CafeMocha.dark" 
 def white(self): print "CafeMocha.white" 
##
class CafeLate(Coffee):
 def dark(self): print "CafeLate.dark" 
 def white(self): print "CafeLate.white" 
##
# Generate coffee name strings:
def caffeeNameGen(n):
 types = Coffee.__subclasses__()
 for i in range(n):
   yield random.choice(types).__name__
##
coffee_name = \
 [ Coffee.factory(i) for i in coffeeNameGen(7)]
##
for coffee in coffee_name:
 coffee.dark()
 coffee.white()
#:~
Factory method in Ruby
class CoffeeFactory  
  def initialize(type)  
     @dark_coffee = self.class.const_get("#{type}Dark")  
     @white_coffee = self.class.const_get("#{type}White")  
  end  
  //
  def new_dark  
     @dark_coffee.new  
  end  
  //
  def new_white  
     @white_coffee.new  
  end  
end  
//
cafe_factory = CoffeeFactory.new('CAFE')  
cafe_dark = cafe_factory.new_dark   
//
late_factory = CoffeeFactory.new('LATE')  
late_white = late_factory.new_white
Factory method in C#
 using System;
 using System.Collections;
 class MainApp
 {
   static void Main()
   {
     // An array of creators 
     Creator[] creators = new Creator[2];
     creators[0] = new ConcreteCreatorA();
     creators[1] = new ConcreteCreatorB();
     //
     // Iterate over creators and create products 
     foreach(Creator creator in creators)
     {
       Product product = creator.FactoryMethod();
       Console.WriteLine("Created {0}", 
         product.GetType().Name);
     }
     //
     // Wait for user 
     Console.Read();
   }
 }
 //
 // "Product" 
 abstract class Product
 {
 }
 //
 // "ConcreteProductA" 
 class ConcreteProductA : Product
 {
 }
 //
 // "ConcreteProductB" 
 class ConcreteProductB : Product
 {
 }
 //
 // "Creator" 
 abstract class Creator
 {
   public abstract Product FactoryMethod();
 }
 //
 // "ConcreteCreator" 
 class ConcreteCreatorA : Creator
 {
   public override Product FactoryMethod()
   {
     return new ConcreteProductA();
   }
 }
 //
 // "ConcreteCreator" 
 class ConcreteCreatorB : Creator
 {
   public override Product FactoryMethod()
   {
     return new ConcreteProductB();
   }
 }
 //
 Created ConcreteProductA
 Created ConcreteProductB

Benefits of Factory Methods

  • It gives a clear separation between the application and a family of classes introducing weak coupling instead of tight coupling by hiding concrete classes from the application. The advantage lies for doing this is the simple way of extending the family of products with minor changes in application code.
  • When the objects are created directly inside the class it's hard to replace them by objects which extend their functionality. If a factory is used instead to create a family of objects the customized objects can easily replace the original objects, configuring the factory to create them.

Limitations of factory pattern

In spite of advantages of factory method there are few limitations of factory method.

  • The main limitation is this pattern is very difficult to refactor.
  • Another difficulty is that the subclasses can't be extended as the pattern initializes the constructor as private. Generally the subclasses inherit the superclass constructor but here in this case it can not be done as the superclass constructor is always private.
  • This difficulty can be overcome by changing constructor type from private to protected but the problem is then the subclasses need to re implement all the methods again with same signature.
  • Factory method is used only for a family of objects. If there is no common base class or interface then this pattern can't be used.

Specific problems and implementation

While applying this pattern to an already written code some problems may arise depending on how the Creator Class is defined already.

What is a Creator class?
  • Creator class is abstract and generating method which does not have any implementation. In this case the ConcreteCreator classes must define their own generation method and this situation usually appears in the cases where the Creator class can't foresee what Concrete Product it will instantiate.
  • Creator class is a concrete class, the generating method having a default implementation. In this situation, the ConcreteCreator classes will use the generating method for flexibility rather than for generation. The programmer will always be able to modify the class of the objects that the Creator class implicitly creates, redefining the generation method.

Factory method is just a particular case of the factory design pattern. In modern programming languages the factory with registration is more used.

Conclusion

The main reason for which the factory pattern is used is that it introduces a separation between the application and a family of classes (it introduces weak coupling instead of tight coupling hiding concrete classes from the application). It provides a simple way of extending the family of products with minor changes in application code.It provides customization hooks. When the objects are created directly inside the class it's hard to replace them by objects which extend their functionality. If a factory is used instead to create a family of objects the customized objects can easily replace the original objects, configuring the factory to create them.The factory has to be used for a family of objects. If the classes doesn't extend common base class or interface they can not be used in a factory design template.

The factory method is one of the most used and one of the more robust design patterns. There are only few points which have to be considered when you implement a factory method.

When you design an application just think if you really need it a factory to create objects. Maybe using it will bring unnecessary complexity in your application. Anyway if you have many object of the same base type and you manipulate them mostly as abstract objects, then you need a factory.

References

[1] http://wapedia.mobi/en/Creational_pattern - Creational pattern

[2] http://www.artima.com/forums/flat.jsp?forum=17&thread=80613 - Prototype pattern

[3] http://en.wikipedia.org/wiki/Factory_method - Factory method

[4] http://www.allapplabs.com/java_design_patterns/factory_pattern.htm - Factory method

[5] http://sourcemaking.com/design_patterns/factrory_method/c%2523 - Factory method in C#

[6] http://www.oodesign.com/factory-method-pattern.html