Abstract Factory |
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
Frequency of use: medium high
|
UML class diagram |
|
Participants |
- AbstractFactory (ContinentFactory)
- declares an interface for operations that create abstract products
- ConcreteFactory (AfricaFactory, AmericaFactory)
- implements the operations to create concrete product objects
- AbstractProduct (Herbivore, Carnivore)
- declares an interface for a type of product object
- Product (Wildebeest, Lion, Bison, Wolf)
- defines a product object to be created by the corresponding concrete factory
- implements the AbstractProduct interface
- Client (AnimalWorld)
- uses interfaces declared by AbstractFactory and AbstractProduct classes
|
Sample code |
This structural code demonstrates the Abstract Factory pattern creating parallel hierarchies of objects. Object creation has been abstracted and there is no need for hard-coded class names in the client code.
// Abstract Factory pattern -- Structural example
//-------------------------------------------------------- // Copyright (C) 2001 - 2002, Data & Object Factory // All rights reserved. www.dofactory.com // // You are free to use this source code in your // applications as long as the original copyright // notice is included. // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT // WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, // INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. //--------------------------------------------------------
using System;
// "AbstractFactory" abstract class AbstractFactory { // Methods abstract public AbstractProductA CreateProductA(); abstract public AbstractProductB CreateProductB(); }
// "ConcreteFactory1" class ConcreteFactory1 : AbstractFactory { // Methods override public AbstractProductA CreateProductA() { return new ProductA1(); } override public AbstractProductB CreateProductB() { return new ProductB1(); } }
// "ConcreteFactory2" class ConcreteFactory2 : AbstractFactory { // Methods override public AbstractProductA CreateProductA() { return new ProductA2(); } override public AbstractProductB CreateProductB() { return new ProductB2(); } }
// "AbstractProductA"
abstract class AbstractProductA { }
// "AbstractProductB" abstract class AbstractProductB { // Methods abstract public void Interact( AbstractProductA a ); }
// "ProductA1" class ProductA1 : AbstractProductA { }
// "ProductB1" class ProductB1 : AbstractProductB { // Methods override public void Interact( AbstractProductA a ) { Console.WriteLine( this + " interacts with " + a ); } }
// "ProductA2" class ProductA2 : AbstractProductA { }
// "ProductB2" class ProductB2 : AbstractProductB { // Methods override public void Interact( AbstractProductA a ) { Console.WriteLine( this + " interacts with " + a ); } }
// "Client" - the interaction environment of the products class Environment { // Fields private AbstractProductA AbstractProductA; private AbstractProductB AbstractProductB;
// Constructors public Environment( AbstractFactory factory ) { AbstractProductB = factory.CreateProductB(); AbstractProductA = factory.CreateProductA(); } // Methods public void Run() { AbstractProductB.Interact( AbstractProductA ); } }
/// <summary> /// ClientApp test environment /// </summary> class ClientApp { public static void Main(string[] args) { AbstractFactory factory1 = new ConcreteFactory1(); Environment e1 = new Environment( factory1 ); e1.Run();
AbstractFactory factory2 = new ConcreteFactory2(); Environment e2 = new Environment( factory2 ); e2.Run();
Console.Read(); } }
|
This real-world code demonstrates the creation of different animal worlds for a computer game using different factories. Although the animals created by the Continent factories are different, the interactions among the animals remain the same.
// Abstract Factory pattern -- Real World example
//-------------------------------------------------------- // Copyright (C) 2001 - 2002, Data & Object Factory // All rights reserved. www.dofactory.com // // You are free to use this source code in your // applications as long as the original copyright // notice is included. // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT // WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, // INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. //--------------------------------------------------------
using System;
// "AbstractFactory" abstract class ContinentFactory { // Methods abstract public Herbivore CreateHerbivore(); abstract public Carnivore CreateCarnivore(); }
// "ConcreteFactory1" class AfricaFactory : ContinentFactory { // Methods override public Herbivore CreateHerbivore() { return new Wildebeest(); } override public Carnivore CreateCarnivore() { return new Lion(); } }
// "ConcreteFactory2" class AmericaFactory : ContinentFactory { // Methods override public Herbivore CreateHerbivore() { return new Bison(); } override public Carnivore CreateCarnivore() { return new Wolf(); } }
// "AbstractProductA" abstract class Herbivore { }
// "AbstractProductB" abstract class Carnivore { // Methods abstract public void Eat( Herbivore h ); }
// "ProductA1" class Wildebeest : Herbivore { }
// "ProductB1" class Lion : Carnivore { // Methods override public void Eat( Herbivore h ) { // eat wildebeest Console.WriteLine( this + " eats " + h ); } }
// "ProductA2" class Bison : Herbivore { }
// "ProductB2" class Wolf : Carnivore { // Methods override public void Eat( Herbivore h ) { // Eat bison Console.WriteLine( this + " eats " + h ); } }
// "Client" class AnimalWorld { // Fields private Herbivore herbivore; private Carnivore carnivore;
// Constructors public AnimalWorld( ContinentFactory factory ) { carnivore = factory.CreateCarnivore(); herbivore = factory.CreateHerbivore(); }
// Methods public void RunFoodChain() { carnivore.Eat( herbivore ); } }
/// <summary> /// GameApp test class /// </summary> class GameApp { public static void Main( string[] args ) { // Create and run the Africa animal world ContinentFactory africa = new AfricaFactory(); AnimalWorld world = new AnimalWorld( africa ); world.RunFoodChain();
// Create and run the America animal world ContinentFactory america = new AmericaFactory(); world = new AnimalWorld( america ); world.RunFoodChain();
Console.Read(); } }
|