본문바로가기

  

Creational Patterns

Abstract Factory

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 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();

}

}

Output

ProductB1 interacts with ProductA1
ProductB2 interacts with ProductA2

 

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();

}

}

Output

Lion eats Wildebeest
Wolf eats Bison