CSC/ECE 517 Fall 2009/wiki3 6 Factory Design Pattern: Difference between revisions
No edit summary |
|||
Line 2: | Line 2: | ||
==Introduction to Design Patterns== | ==Introduction to Design Patterns== | ||
In software engineering, a design pattern is a general reusable solution to a commonly occurring problem in software design. 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. | "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)[http://c2.com/cgi/wiki?GangOfFour]. 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. | ||
Design patterns reside in the domain of modules and interconnections. At a higher level there are Architectural patterns that are larger in scope, usually describing an overall pattern followed by an entire system. | Design patterns reside in the domain of modules and interconnections. At a higher level there are Architectural patterns that are larger in scope, usually describing an overall pattern followed by an entire system. |
Revision as of 13:09, 17 November 2009
"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.
Design patterns reside in the domain of modules and interconnections. At a higher level there are Architectural patterns that are larger in scope, usually describing an overall pattern followed by an entire system.
Classification and list
Design patterns were originally grouped into the categories Creational patterns, Structural patterns, and Behavioral patterns, and described them using the concepts of delegation, aggregation, and consultation. For further background on object-oriented design, see coupling and cohesion. For further background on object-oriented programming, see inheritance, interface, and polymorphism. 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.
Creational patterns
What is creational pattern
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 factory is the place to take centralize decision of what 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 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
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 of factory method
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
Limitations
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.
Conclusion
Index
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#