Abstract factory pattern

Abstract factory – Definition

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

Gang of four (Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides)

Abstract factory – Pseudocode

// in einer abstrakten Fabrik, gibt es verschiedene Produkte, die man erstellen
// möchte. Für jede Produktvariante soll ein Interface erstellt werden
interface ProductA
interface ProductB

// anschließend werden für jede Produktausprägung eine eigene Klasse erstellt
// um die Logik voneinander zu kapseln.
// Ähnelt sich die Logik, können auch abstrakte Klassen erstellt werden und
// an die konkreten Klassen, bzw. Produktausprägungen weiter vererbt werden
class ConcreteProductA1 implement ProductA
class ConcreteProductA2 implement ProductA
class ConcreteProductB1 implement ProductB
class ConcreteProductB2 implement ProductB

// Es gibt ein allgemeines Interface, welches die jeweiligen Ausprägungen
// für die Produkte erstellen soll
interface Factory
	method createA() returns ProductA
	method createB() returns ProductB

// Eine konkrete Fabrik erstellt ein Produkt einer bestimmten Produktfamilie,
// die zu einer bestimmten Ausprägungen gehört. Die Fabrik stellt sicher, dass
// die jeweiligen Produkte alle miteinander kompatibel sind.
class ConcreteFactory1 implements Factory
	method createA() returns ProductA
		return ConcreteProductA1()
		
	method createB() returns ProductB
		return ConcreteProductB1()

// Jede Fabrik erstellt die eigenen Produktvariationen
class ConcreteFactory2 implement Factory
	method createA() returns ProductA
		return ConcreteProductA2()
		
	method createB() returns ProductB
		return ConcreteProductB2()
		
// Die eigentliche Logik braucht sich jetzt nicht mehr um die einzelnen
// Ausprägungen zu kümmern. Es wird darauf vertraut, dass die Produkte sich
// gleich verhalten.
// Dabei spielt es keine Rolle, welche Variationen schlussendlich verwendet 
// werden, solange die gemeinsame Schnittstelle klar definiert ist.
class Context
	field productA
	field productB
	
	constructor (factory)
		this.productA = factory.createA()
		this.productB = factory.createB()
	
	method operation()
		this.productA.operation()
		this.productB.operation()

program Client
	// Das Program muss jetzt nur noch entscheiden, welche Variationen verwendet
	// werden sollen.
	var context = new Context(ConcreteFactory1)
	context.operation()	// A1 + B1
	
	var context = new Context(ConcreteFactory2)
	context.operation()	// A2 + B2