[Design Pattern]GoF 의 Design Pattern - Creational Patterns - Abstract Factory
Creational Patterns
Definition
: 구체적인 클래스들을 명시하지 않고 관련이 있거나 의존적인 객체 군을 생성 하기 위한 인터페이스를 제공한다.
분류 |
설명 |
이름(Name) |
Abstract Factory |
의도(Insert) |
여러분은 특정 클라이언트를 위한 객체 집합이나 군을 갖기를 원한다. |
문제점(Problem) |
관련된 객체 군은 인스턴스화되어야 한다. |
해결법(Solution) |
패턴객체 군의 생성 시기를 조정하자. 생성된 객체를 이용하는 클라이언트 객체 밖에서 인스튼스화를 수행하는 방법에 대한 규칙을 얻는 방법을 제공하자. |
관계자(Participant)와 협력자(Collaborator) |
AbstractFactory는 요구되는 객체 군의 각 멤버를 생성하는 방법을 위한 인터페이스를 정의한다. 일반적으로, 각각의 군은 자신의 유일한 ConcreteFactory를 가짐으로써 객체로 생성된다. |
결과(Consequence) |
이 패턴은 객체를 이용하는 방법에 대한 로직으로부터 어떤 객체를 이용할 것인가 하는 규칙들을 분리한다. |
구현(Implementation) |
어떤 객체가 만들어지는지를 명시한 추상 클래스를 정의하자. 그런 다음 객체들의 각 군을 위해 하나의 구체적인 클래스를구현하자. 데이터 베이스의 테이블이나 파일 또는 작업을 수행하는 데 이용될 수 있다. |
UML class diagram
Participants
: The classes and/or objects participating in this pattern are:
. 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 in C#
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 { AbstractFactory factory1 = new ConcreteFactory1(); Environment e1 = new Environment( factory1 ); e1.Run(); AbstractFactory factory2 = new ConcreteFactory2(); Environment e2 = new Environment( factory2 ); e2.Run(); Console.Read(); } } Output ProductB1 interacts with ProductA1 |
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 { // Create and run the ContinentFactory AnimalWorld world = new AnimalWorld( world.RunFoodChain(); // Create and run the ContinentFactory world = new AnimalWorld( world.RunFoodChain(); Console.Read(); } } Output Lion eats Wildebeest |