CSC/ECE 517 Fall 2012/ch2b 2w57: Difference between revisions
No edit summary |
|||
(30 intermediate revisions by the same user not shown) | |||
Line 12: | Line 12: | ||
== Motivation == | == Motivation == | ||
[http://en.wikipedia.org/wiki/Modular_programming Modularization] is a big issue in today's programming. Programmers all over the world are trying to avoid the idea of adding code to existing classes in order to make them support encapsulating more general information. Take the case of a information manager which manages phone number. Phone numbers have a particular rule on which they get generated depending on areas and countries. If at some point the application should be changed in order to support adding numbers | [http://en.wikipedia.org/wiki/Modular_programming Modularization] is a big issue in today's programming. Programmers all over the world are trying to avoid the idea of adding code to existing classes in order to make them support encapsulating more general information. Take the case of a information manager which manages phone number. Phone numbers have a particular rule on which they get generated depending on areas and countries. If at some point the application should be changed in order to support adding numbers from a new country, the code of the application would have to be changed and it would become more and more complicated. | ||
In order to prevent it, the Abstract Factory design pattern is used. Using this pattern a framework is defined, which produces objects that follow a general pattern and at runtime this factory is paired with any concrete factory to produce objects that follow the pattern of a certain country. In other words, the Abstract Factory is a super-factory which creates other factories (Factory of factories). | In order to prevent it, the Abstract Factory design pattern is used. Using this pattern a framework is defined, which produces objects that follow a general pattern and at runtime this factory is paired with any concrete factory to produce objects that follow the pattern of a certain country. In other words, the Abstract Factory is a super-factory which creates other factories (Factory of factories). | ||
The following websites provide a good overview and general overall explanation of the Abstract Factory Pattern: | |||
http://en.wikipedia.org/wiki/Abstract_factory_pattern | |||
http://www.oodesign.com/abstract-factory-pattern.html | |||
http://sourcemaking.com/design_patterns/abstract_factory | |||
http://www.developer.com/design/article.php/626001/Pattern-Summaries-Abstract-Factory-Pattern.htm | |||
= Usage = | = Usage = | ||
Line 26: | Line 36: | ||
= Structure = | = Structure = | ||
== | === UML Diagram === | ||
The following diagram shows the UML representation of the Abstract Factory. | |||
[[File:Abstract factory UML.png]] | |||
The following sites show more UML diagrams with explanantions: | |||
http://www.codeproject.com/Articles/331304/Understanding-and-Implementing-Abstract-Factory-Pa | |||
http://apwebco.com/gofpatterns/creational/AbstractFactory.html | |||
== | = Examples = | ||
In this section, we show implementation examples of the Abstract Factory in different languages. The output of each should be either "I'm a WinButton" or "I'm an OSXButton" depending on which kind of factory was used. Note that the Application has no idea what kind of GUIFactory it is given or even what kind of Button that factory creates. This same code can be found at http://en.wikipedia.org/wiki/Abstract_factory_pattern#Example | |||
[[ | === C++ === | ||
/* GUIFactory example */ | |||
#include <iostream> | |||
class Button { | |||
public: | |||
virtual void paint() = 0; | |||
virtual ~Button() { } | |||
}; | |||
class WinButton : public Button { | |||
public: | |||
void paint() { | |||
std::cout << "I'm a WinButton"; | |||
} | |||
}; | |||
class OSXButton : public Button { | |||
public: | |||
void paint() { | |||
std::cout << "I'm an OSXButton"; | |||
} | |||
}; | |||
class GUIFactory { | |||
public: | |||
virtual Button* createButton() = 0; | |||
virtual ~GUIFactory() { } | |||
}; | |||
class WinFactory : public GUIFactory { | |||
public: | |||
Button* createButton() { | |||
return new WinButton(); | |||
} | |||
~WinFactory() { } | |||
}; | |||
class OSXFactory : public GUIFactory { | |||
public: | |||
Button* createButton() { | |||
return new OSXButton(); | |||
} | |||
~OSXFactory() { } | |||
}; | |||
class Application { | |||
public: | |||
Application(GUIFactory* factory) { | |||
Button* button = factory->createButton(); | |||
button->paint(); | |||
delete button; | |||
delete factory; | |||
} | |||
}; | |||
GUIFactory* createOsSpecificFactory() { | |||
int sys; | |||
std::cout "\nEnter OS type (0: Windows, 1: MacOS X): "; | |||
std::cin >> sys; | |||
if (sys == 0) { | |||
return new WinFactory(); | |||
} else { | |||
return new OSXFactory(); | |||
} | |||
} | |||
int main() { | |||
Application application(createOsSpecificFactory()); | |||
} | |||
More examples in C++ can be found here: | |||
http://sourcemaking.com/design_patterns/abstract_factory/cpp/1 | |||
http://sourcemaking.com/design_patterns/abstract_factory/cpp/2 | |||
http://www.codeproject.com/Articles/331304/Understanding-and-Implementing-Abstract-Factory-Pa | |||
http://r3dux.org/2011/07/an-example-abstract-factory-design-pattern-implementation-in-c/ | |||
===C#=== | |||
/* GUIFactory example -- */ | |||
using System; | |||
using System.Configuration; | |||
namespace AbstractFactory | |||
{ | |||
public interface IButton | |||
{ | |||
void Paint(); | |||
} | |||
public interface IGUIFactory | |||
{ | |||
IButton CreateButton(); | |||
} | |||
public class OSXButton : IButton // Executes fourth if OS:OSX | |||
{ | |||
public void Paint() | |||
{ | |||
System.Console.WriteLine("I'm an OSXButton"); | |||
} | |||
} | |||
public class WinButton : IButton // Executes fourth if OS:WIN | |||
{ | |||
public void Paint() | |||
{ | |||
System.Console.WriteLine("I'm a WinButton"); | |||
} | |||
} | |||
public class OSXFactory : IGUIFactory // Executes third if OS:OSX | |||
{ | |||
IButton IGUIFactory.CreateButton() | |||
{ | |||
return new OSXButton(); | |||
} | |||
} | |||
public class WinFactory : IGUIFactory // Executes third if OS:WIN | |||
{ | |||
IButton IGUIFactory.CreateButton() | |||
{ | |||
return new WinButton(); | |||
} | |||
} | |||
public class Application | |||
{ | |||
public Application(IGUIFactory factory) | |||
{ | |||
IButton button = factory.CreateButton(); | |||
button.Paint(); | |||
} | |||
} | |||
public class ApplicationRunner | |||
{ | |||
static IGUIFactory CreateOsSpecificFactory() // Executes second | |||
{ | |||
// Contents of App{{Not a typo|.}}Config associated with this C# project | |||
//<?xml version="1.0" encoding="utf-8" ?> | |||
//<configuration> | |||
// <appSettings> | |||
// <!-- Uncomment either Win or OSX OS_TYPE to test --> | |||
// <add key="OS_TYPE" value="Win" /> | |||
// <!-- <add key="OS_TYPE" value="OSX" /> --> | |||
// </appSettings> | |||
//</configuration> | |||
string sysType = ConfigurationSettings.AppSettings["OS_TYPE"]; | |||
if (sysType == "Win") | |||
{ | |||
return new WinFactory(); | |||
} | |||
else | |||
{ | |||
return new OSXFactory(); | |||
} | |||
} | |||
static void Main(string[] args) // Executes first | |||
{ | |||
new Application(CreateOsSpecificFactory()); | |||
Console.ReadLine(); | |||
} | |||
} | |||
} | |||
More examples in C# can be found in the following sites: | |||
http://www.codeproject.com/Articles/19240/C-Abstract-Factory-Pattern | |||
http://www.dofactory.com/Patterns/PatternAbstract.aspx | |||
http://www.codeproject.com/Articles/328373/Understanding-and-Implementing-Abstract-Factory-Pa | |||
http://sourcemaking.com/design_patterns/abstract_factory/c%2523 | |||
=== Java === | |||
/* GUIFactory example -- */ | |||
interface Button { | |||
void paint(); | |||
} | |||
interface GUIFactory { | |||
Button createButton(); | |||
} | |||
class WinFactory implements GUIFactory { | |||
public Button createButton() { | |||
return new WinButton(); | |||
} | |||
} | |||
class OSXFactory implements GUIFactory { | |||
public Button createButton() { | |||
return new OSXButton(); | |||
} | |||
} | |||
class WinButton implements Button { | |||
public void paint() { | |||
System.out.println("I'm a WinButton"); | |||
} | |||
} | |||
class OSXButton implements Button { | |||
public void paint() { | |||
System.out.println("I'm an OSXButton"); | |||
} | |||
} | |||
class Application { | |||
public Application(GUIFactory factory) { | |||
Button button = factory.createButton(); | |||
button.paint(); | |||
} | |||
} | |||
public class ApplicationRunner { | |||
public static void main(String[] args) { | |||
new Application(createOsSpecificFactory()); | |||
} | |||
public static GUIFactory createOsSpecificFactory() { | |||
int sys = readFromConfigFile("OS_TYPE"); | |||
if (sys == 0) return new WinFactory(); | |||
else return new OSXFactory(); | |||
} | |||
} | |||
More examples in Java can be found here: | |||
http://sourcemaking.com/design_patterns/abstract_factory/java/2 | |||
http://sourcemaking.com/design_patterns/abstract_factory/java/1 | |||
http://apwebco.com/gofpatterns/creational/AbstractFactory.html | |||
http://java.dzone.com/articles/design-patterns-abstract-factory | |||
http://www.java2s.com/Code/Java/Design-Pattern/AbstractFactoryPatternExample.htm | |||
http://www.allapplabs.com/java_design_patterns/abstract_factory_pattern.htm | |||
= Comparison with other patterns = | = Comparison with other patterns = | ||
== Factory Pattern == | === Factory Pattern === | ||
The main difference between a "factory method" and an "abstract factory" is that the factory method is a single method, and an abstract factory is an object | The [http://en.wikipedia.org/wiki/Factory_method_pattern Factory Method Pattern] is an object-oriented creational design pattern to implement the concept of [http://en.wikipedia.org/wiki/Factory_(software_concept) factories] and deals with the problem of creating objects (products) without specifying the exact class of object that will be created. The essence of this pattern is to "Define an interface for creating an object, but let the classes that implement the interface decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses. | ||
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. | |||
The main difference between a "factory method" and an "abstract factory" is that the factory method is a single method, and an abstract factory is an object. The following websites further explain the difference between Abstract Factory and Factory Method in detail. | |||
http://stackoverflow.com/questions/5739611/differences-between-abstract-factory-pattern-and-factory-method | http://stackoverflow.com/questions/5739611/differences-between-abstract-factory-pattern-and-factory-method | ||
http://stackoverflow.com/questions/1001767/what-is-the-basic-difference-between-factory-and-abstract-factory-patterns | |||
http://www.codeproject.com/Articles/35789/Understanding-Factory-Method-and-Abstract-Factory | http://www.codeproject.com/Articles/35789/Understanding-Factory-Method-and-Abstract-Factory | ||
http://www.dofactory.com/topic/1284/abstract-factory-vs-factory-method.aspx | |||
http://stackoverflow.com/questions/4209791/design-patterns-abstract-factory-vs-factory-method | http://stackoverflow.com/questions/4209791/design-patterns-abstract-factory-vs-factory-method | ||
== Bridge Pattern == | === Bridge Pattern === | ||
The [http://en.wikipedia.org/wiki/Bridge_pattern bridge pattern] is a design pattern used in software engineering which is meant to "decouple an abstraction from its implementation so that the two can vary independently". The bridge uses encapsulation, aggregation, and can use inheritance to separate responsibilities into different classes. | The [http://en.wikipedia.org/wiki/Bridge_pattern bridge pattern] is a design pattern used in software engineering which is meant to "decouple an abstraction from its implementation so that the two can vary independently". The bridge uses encapsulation, aggregation, and can use inheritance to separate responsibilities into different classes. | ||
Line 62: | Line 345: | ||
http://www.felix-colibri.com/papers/design_patterns/factory_and_bridge_patterns/factory_and_bridge_patterns.html | http://www.felix-colibri.com/papers/design_patterns/factory_and_bridge_patterns/factory_and_bridge_patterns.html | ||
== Builder Pattern == | === Builder Pattern === | ||
The [http://en.wikipedia.org/wiki/Builder_pattern builder pattern] is an [http://en.wikipedia.org/wiki/Creational_pattern object creation] software design pattern. The intention is to abstract steps of construction of objects so that different implementations of these steps can construct different representations of objects. Often, the builder pattern is used to build products in accordance with the [http://en.wikipedia.org/wiki/Composite_pattern composite pattern]. | The [http://en.wikipedia.org/wiki/Builder_pattern builder pattern] is an [http://en.wikipedia.org/wiki/Creational_pattern object creation] software design pattern. The intention is to abstract steps of construction of objects so that different implementations of these steps can construct different representations of objects. Often, the builder pattern is used to build products in accordance with the [http://en.wikipedia.org/wiki/Composite_pattern composite pattern]. | ||
Line 79: | Line 362: | ||
http://www.oodesign.com/builder-pattern.html | http://www.oodesign.com/builder-pattern.html | ||
== Strategy Pattern == | === Strategy Pattern === | ||
The [http://en.wikipedia.org/wiki/Strategy_pattern strategy pattern] (also known as the policy pattern) is a particular software design pattern, whereby algorithms behaviour can be selected at runtime. Formally speaking, the strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it. | The [http://en.wikipedia.org/wiki/Strategy_pattern strategy pattern] (also known as the policy pattern) is a particular software design pattern, whereby algorithms behaviour can be selected at runtime. Formally speaking, the strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it. | ||
Line 91: | Line 374: | ||
== Prototype Pattern == | === Prototype Pattern === | ||
The [http://en.wikipedia.org/wiki/Prototype_pattern prototype pattern] is a creational design pattern used in software development when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects. | The [http://en.wikipedia.org/wiki/Prototype_pattern prototype pattern] is a creational design pattern used in software development when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects. | ||
The motivation behind this pattern is to: | The motivation behind this pattern is to: | ||
Line 106: | Line 389: | ||
=References= | =References= | ||
* | *http://en.wikipedia.org/wiki/Abstract_factory_pattern | ||
*Freeman, Eric; Freeman, Elisabeth; Kathy, Sierra; Bert, Bates (2004). Hendrickson, Mike. ed (paperback). [http://it-ebooks.info/book/252/ ''Head First Design Patterns''] | |||
* [|[http://www.informit.com/authors/bio.aspx?a=725735c6-e618-488a-9f9b-a3b8344570dc Gamma, Erich]]; Richard Helm, Ralph Johnson, John M. Vlissides (2009-10-23). [http://www.informit.com/articles/article.aspx?p=1398599 "Design Patterns: Abstract Factory"] | |||
* [|[http://www.codeproject.com/script/Membership/View.aspx?mid=319264 Veeneman, David]] (2009-10-23). [http://www.codeproject.com/Articles/4079/Object-Design-for-the-Perplexed "Object Design for the Perplexed"] | |||
* [http://www.oodesign.com/abstract-factory-pattern.html "Abstract Factory: Implementation"] | |||
*http://www.oodesign.com/strategy-pattern.html | |||
*http://en.wikipedia.org/wiki/Strategy_pattern | |||
*http://en.wikipedia.org/wiki/Creational_pattern | |||
*http://en.wikipedia.org/wiki/Behavioral_pattern | |||
*http://www.oodesign.com/prototype-pattern.html | |||
*http://sourcemaking.com/design_patterns/prototype | |||
*http://en.wikipedia.org/wiki/Prototype_pattern | |||
*http://stackoverflow.com/questions/5739240/questions-about-the-prototype-pattern | |||
*Scott Walters (2004). [http://perldesignpatterns.com/?CompositePattern Perl Design Patterns Book] | |||
*Geary, David (13 Sep 2002). [http://www.javaworld.com/javaworld/jw-09-2002/jw-0913-designpatterns.html "A look at the Composite design pattern"] | |||
*http://www.oodesign.com/bridge-pattern.html | |||
*http://wgao.blogspot.com/2004/11/bridge-pattern-and-abstract-factory.html | |||
*http://en.wikipedia.org/wiki/Bridge_pattern | |||
*http://sourcemaking.com/design_patterns/bridge | |||
*http://stackoverflow.com/questions/7700854/abstractfactory-versus-bridge-pattern | |||
*http://www.felix-colibri.com/papers/design_patterns/factory_and_bridge_patterns/factory_and_bridge_patterns.html | |||
*http://en.wikipedia.org/wiki/Factory_(software_concept) | |||
*http://en.wikipedia.org/wiki/Factory_method_pattern | |||
*http://www.oodesign.com/factory-method-pattern.html | |||
*http://www.oodesign.com/builder-pattern.html | |||
*http://en.wikipedia.org/wiki/Builder_pattern | |||
*http://www.codeproject.com/Articles/19240/C-Abstract-Factory-Pattern | |||
*http://www.dofactory.com/Patterns/PatternAbstract.aspx | |||
*http://www.codeproject.com/Articles/328373/Understanding-and-Implementing-Abstract-Factory-Pa | |||
*http://www.oodesign.com/abstract-factory-pattern.html | |||
*http://sourcemaking.com/design_patterns/abstract_factory/cpp/1 | |||
*http://sourcemaking.com/design_patterns/abstract_factory/cpp/2 | |||
*http://www.codeproject.com/Articles/331304/Understanding-and-Implementing-Abstract-Factory-Pa | |||
* | *http://r3dux.org/2011/07/an-example-abstract-factory-design-pattern-implementation-in-c/ |
Latest revision as of 04:23, 20 November 2012
Abstract Factory: A directory of sites
The objective of this wiki is to provide a directory of sites that one would refer to while learning about the Abstract Factory pattern. Therefore, in this wiki, we will be giving an overview of the different features of the Abstract Factory pattern along with links to useful websites that explain each of these features in more detail.
Introduction
The abstract factory pattern is a software creational design pattern that provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes. In normal usage, the client software creates a concrete implementation of the abstract factory and then uses the generic interfaces to create the concrete objects that are part of the theme. The client does not know (or care) which concrete objects it gets from each of these internal factories, since it uses only the generic interfaces of their products. This pattern separates the details of implementation of a set of objects from their general usage and relies on object composition, as object creation is implemented in methods exposed in the factory interface.
The essence of the Abstract Factory Pattern is to "Provide an interface for creating families of related or dependent objects without specifying their concrete classes".
Motivation
Modularization is a big issue in today's programming. Programmers all over the world are trying to avoid the idea of adding code to existing classes in order to make them support encapsulating more general information. Take the case of a information manager which manages phone number. Phone numbers have a particular rule on which they get generated depending on areas and countries. If at some point the application should be changed in order to support adding numbers from a new country, the code of the application would have to be changed and it would become more and more complicated.
In order to prevent it, the Abstract Factory design pattern is used. Using this pattern a framework is defined, which produces objects that follow a general pattern and at runtime this factory is paired with any concrete factory to produce objects that follow the pattern of a certain country. In other words, the Abstract Factory is a super-factory which creates other factories (Factory of factories).
The following websites provide a good overview and general overall explanation of the Abstract Factory Pattern:
http://en.wikipedia.org/wiki/Abstract_factory_pattern
http://www.oodesign.com/abstract-factory-pattern.html
http://sourcemaking.com/design_patterns/abstract_factory
http://www.developer.com/design/article.php/626001/Pattern-Summaries-Abstract-Factory-Pattern.htm
Usage
The factory determines the actual concrete type of object to be created, and it is here that the object is actually created (in C++, for instance, by the new operator). However, the factory only returns an abstract pointer to the created concrete object. This insulates client code from object creation by having clients ask a factory object to create an object of the desired abstract type and to return an abstract pointer to the object. As the factory only returns an abstract pointer, the client code (that requested the object from the factory) does not know – and is not burdened by – the actual concrete type of the object that was just created. However, the type of a concrete object (and hence a concrete factory) is known by the abstract factory; for instance, the factory may read it from a configuration file. The client has no need to specify the type, since it has already been specified in the configuration file. In particular, this means:
- The client code has no knowledge whatsoever of the concrete type, not needing to include any header files or class declarations related to it. The client code deals only with the abstract type. Objects of a concrete type are indeed created by the factory, but the client code accesses such objects only through their abstract interface.
- Adding new concrete types is done by modifying the client code to use a different factory, a modification that is typically one line in one file. (The different factory then creates objects of a different concrete type, but still returns a pointer of the same abstract type as before – thus insulating the client code from change.) This is significantly easier than modifying the client code to instantiate a new type, which would require changing every location in the code where a new object is created (as well as making sure that all such code locations also have knowledge of the new concrete type, by including for instance a concrete class header file). If all factory objects are stored globally in a singleton object, and all client code goes through the singleton to access the proper factory for object creation, then changing factories is as easy as changing the singleton object.
Structure
UML Diagram
The following diagram shows the UML representation of the Abstract Factory.
The following sites show more UML diagrams with explanantions:
http://www.codeproject.com/Articles/331304/Understanding-and-Implementing-Abstract-Factory-Pa
http://apwebco.com/gofpatterns/creational/AbstractFactory.html
Examples
In this section, we show implementation examples of the Abstract Factory in different languages. The output of each should be either "I'm a WinButton" or "I'm an OSXButton" depending on which kind of factory was used. Note that the Application has no idea what kind of GUIFactory it is given or even what kind of Button that factory creates. This same code can be found at http://en.wikipedia.org/wiki/Abstract_factory_pattern#Example
C++
/* GUIFactory example */ #include <iostream> class Button { public: virtual void paint() = 0; virtual ~Button() { } }; class WinButton : public Button { public: void paint() { std::cout << "I'm a WinButton"; } }; class OSXButton : public Button { public: void paint() { std::cout << "I'm an OSXButton"; } }; class GUIFactory { public: virtual Button* createButton() = 0; virtual ~GUIFactory() { } }; class WinFactory : public GUIFactory { public: Button* createButton() { return new WinButton(); } ~WinFactory() { } }; class OSXFactory : public GUIFactory { public: Button* createButton() { return new OSXButton(); } ~OSXFactory() { } }; class Application { public: Application(GUIFactory* factory) { Button* button = factory->createButton(); button->paint(); delete button; delete factory; } }; GUIFactory* createOsSpecificFactory() { int sys; std::cout "\nEnter OS type (0: Windows, 1: MacOS X): "; std::cin >> sys; if (sys == 0) { return new WinFactory(); } else { return new OSXFactory(); } } int main() { Application application(createOsSpecificFactory()); }
More examples in C++ can be found here:
http://sourcemaking.com/design_patterns/abstract_factory/cpp/1
http://sourcemaking.com/design_patterns/abstract_factory/cpp/2
http://www.codeproject.com/Articles/331304/Understanding-and-Implementing-Abstract-Factory-Pa
http://r3dux.org/2011/07/an-example-abstract-factory-design-pattern-implementation-in-c/
C#
/* GUIFactory example -- */ using System; using System.Configuration; namespace AbstractFactory { public interface IButton { void Paint(); } public interface IGUIFactory { IButton CreateButton(); } public class OSXButton : IButton // Executes fourth if OS:OSX { public void Paint() { System.Console.WriteLine("I'm an OSXButton"); } } public class WinButton : IButton // Executes fourth if OS:WIN { public void Paint() { System.Console.WriteLine("I'm a WinButton"); } } public class OSXFactory : IGUIFactory // Executes third if OS:OSX { IButton IGUIFactory.CreateButton() { return new OSXButton(); } } public class WinFactory : IGUIFactory // Executes third if OS:WIN { IButton IGUIFactory.CreateButton() { return new WinButton(); } } public class Application { public Application(IGUIFactory factory) { IButton button = factory.CreateButton(); button.Paint(); } } public class ApplicationRunner { static IGUIFactory CreateOsSpecificFactory() // Executes second { // Contents of AppTemplate:Not a typoConfig associated with this C# project //<?xml version="1.0" encoding="utf-8" ?> //<configuration> // <appSettings> // // <add key="OS_TYPE" value="Win" /> // // </appSettings> //</configuration> string sysType = ConfigurationSettings.AppSettings["OS_TYPE"]; if (sysType == "Win") { return new WinFactory(); } else { return new OSXFactory(); } } static void Main(string[] args) // Executes first { new Application(CreateOsSpecificFactory()); Console.ReadLine(); } } }
More examples in C# can be found in the following sites:
http://www.codeproject.com/Articles/19240/C-Abstract-Factory-Pattern
http://www.dofactory.com/Patterns/PatternAbstract.aspx
http://www.codeproject.com/Articles/328373/Understanding-and-Implementing-Abstract-Factory-Pa
http://sourcemaking.com/design_patterns/abstract_factory/c%2523
Java
/* GUIFactory example -- */ interface Button { void paint(); } interface GUIFactory { Button createButton(); } class WinFactory implements GUIFactory { public Button createButton() { return new WinButton(); } } class OSXFactory implements GUIFactory { public Button createButton() { return new OSXButton(); } } class WinButton implements Button { public void paint() { System.out.println("I'm a WinButton"); } } class OSXButton implements Button { public void paint() { System.out.println("I'm an OSXButton"); } } class Application { public Application(GUIFactory factory) { Button button = factory.createButton(); button.paint(); } } public class ApplicationRunner { public static void main(String[] args) { new Application(createOsSpecificFactory()); } public static GUIFactory createOsSpecificFactory() { int sys = readFromConfigFile("OS_TYPE"); if (sys == 0) return new WinFactory(); else return new OSXFactory(); } }
More examples in Java can be found here:
http://sourcemaking.com/design_patterns/abstract_factory/java/2
http://sourcemaking.com/design_patterns/abstract_factory/java/1
http://apwebco.com/gofpatterns/creational/AbstractFactory.html
http://java.dzone.com/articles/design-patterns-abstract-factory
http://www.java2s.com/Code/Java/Design-Pattern/AbstractFactoryPatternExample.htm
http://www.allapplabs.com/java_design_patterns/abstract_factory_pattern.htm
Comparison with other patterns
Factory Pattern
The Factory Method Pattern is an object-oriented creational design pattern to implement the concept of factories and deals with the problem of creating objects (products) without specifying the exact class of object that will be created. The essence of this pattern is to "Define an interface for creating an object, but let the classes that implement the interface decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses.
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.
The main difference between a "factory method" and an "abstract factory" is that the factory method is a single method, and an abstract factory is an object. The following websites further explain the difference between Abstract Factory and Factory Method in detail.
http://www.codeproject.com/Articles/35789/Understanding-Factory-Method-and-Abstract-Factory
http://www.dofactory.com/topic/1284/abstract-factory-vs-factory-method.aspx
http://stackoverflow.com/questions/4209791/design-patterns-abstract-factory-vs-factory-method
Bridge Pattern
The bridge pattern is a design pattern used in software engineering which is meant to "decouple an abstraction from its implementation so that the two can vary independently". The bridge uses encapsulation, aggregation, and can use inheritance to separate responsibilities into different classes.
The motivation behind the Bridge Pattern is that sometimes an abstraction may need to have different implementations: Consider an object that handles persistence of objects over different platforms using either relational databases or file system structures (files and folders). A simple implementation might choose to extend the object itself to implement the functionality for both file system and RDBMS. However this implementation would create a problem: Inheritance binds an implementation to the abstraction and thus it would be difficult to modify, extend, and reuse abstraction and implementation independently.
An Abstract Factory pattern can be used create and configure a particular Bridge, for example a factory can choose the suitable concrete implementor at runtime.
The difference between Abstract Factory and Bridge is further explained in the following sites.
http://wgao.blogspot.com/2004/11/bridge-pattern-and-abstract-factory.html
http://stackoverflow.com/questions/7700854/abstractfactory-versus-bridge-pattern
Builder Pattern
The builder pattern is an object creation software design pattern. The intention is to abstract steps of construction of objects so that different implementations of these steps can construct different representations of objects. Often, the builder pattern is used to build products in accordance with the composite pattern.
The motivation behind the builder pattern is that the complexity of classes and objects which increases as the complexity of the application increases. Complex objects are made of parts produced by other objects that need special care when being built. An application might need a mechanism for building complex objects that is independent from the ones that make up the object.
The builder pattern allows a client object to construct a complex object by specifying only its type and content, being shielded from the details related to the object's representation. This way the construction process can be used to create different representations. The logic of this process is isolated form the actual steps used in creating the complex object, so the process can be used again to create a different object form the same set of simple objects as the first one.
The main difference between Abstract Factory and Builder is that in the case of the Abstract Factory, the client uses the factory's methods to create its own objects whereas in the Builder's case, the Builder class is instructed on how to create the object and then it is asked for it, but the way that the class is put together is up to the Builder class
The difference between Builder pattern and the Abstract Factory pattern is explained in detail in the following sites.
https://sites.google.com/site/sureshdevang/abstract-factory-vs-builder-design-patterns
http://stackoverflow.com/questions/3687299/abstract-factory-factory-method-builder
http://www.oodesign.com/builder-pattern.html
Strategy Pattern
The strategy pattern (also known as the policy pattern) is a particular software design pattern, whereby algorithms behaviour can be selected at runtime. Formally speaking, the strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
The motivation behind the Strategy Pattern is that there are situations when classes differ only in their behavior. In such cases, it is a good idea to isolate the algorithms in separate classes in order to have the ability to select different algorithms at runtime.
The main difference between Abstract Factory and Strategy is that Abstract Factory is a creational pattern whereas Strategy is a behavioral pattern.
Prototype Pattern
The prototype pattern is a creational design pattern used in software development when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects. The motivation behind this pattern is to:
- avoid subclasses of an object creator in the client application, like the abstract factory pattern does.
- avoid the inherent cost of creating a new object in the standard way (e.g., using the 'new' keyword) when it is prohibitively expensive for a given application.
Abstract Factory classes are often implemented with Factory Methods, but they can be implemented using Prototype. This concept is further explained in the following sites.
http://stackoverflow.com/questions/5739240/questions-about-the-prototype-pattern
http://www.oodesign.com/prototype-pattern.html
http://sourcemaking.com/design_patterns/prototype
References
- Freeman, Eric; Freeman, Elisabeth; Kathy, Sierra; Bert, Bates (2004). Hendrickson, Mike. ed (paperback). Head First Design Patterns
- [|Gamma, Erich]; Richard Helm, Ralph Johnson, John M. Vlissides (2009-10-23). "Design Patterns: Abstract Factory"
- [|Veeneman, David] (2009-10-23). "Object Design for the Perplexed"
- Scott Walters (2004). Perl Design Patterns Book
- Geary, David (13 Sep 2002). "A look at the Composite design pattern"