[읽기전에]
UML 다이어그램 : UML클래스 다이어그램 기본상식 http://hongjinhyeon.tistory.com/25
포스팅되는 디자인 패턴의 예는 스타크래프트를 기본으로 하였습니다 : 디자인 패턴을 시작하며 http://hongjinhyeon.tistory.com/24
<기본 정의 >
1. Abstract Factory Pattern 정의
- 구체적인 클래스를 명시하지 않고도 연관되어 있거나 의존적인 객체 패밀리 생성을 위한 인터페이스 제공.
(Provide an interface for creating families of related or dependent objects without specifying their concrete classes.)
- 예를 들어서, 곰 세마리 가족(아빠,엄마,아기) 에 대한 대화형 어플리케이션을 개발한다고 했을때에 그 어플리케이션에서
두가지 종류의 곰(골든베어가족과 브라운베어가족)을 사용자가 선택해서 이야기를 진행하는 기능이 있다면 사용자의 선택
에 따라서 자동으로 하나의 종류의 아빠 엄마 아기가 생성되어야 한다. 그때 골든베어를 선택하면 자동으로 GoldenDadBear,
GoldenMomBear, GoldenBabyBear 를 생성해주고 반대로 브라운을 선택하면 BrownDadBear, BrownMomBear, BrownBabyBear
을 생성해주어야 한다.
- 즉, 비슷한 기능을 하지만 종류가 다른 클래스들을 생성하는 인터페이스 제공한다.
2.UML Diagram
3. 사용 용도 및 장점
-Factory Method Pattern의 장점을 거의 동일하게 가진다.
①객체의 생성을 한군데에서 관리를 할수가 있다. (ConcreteCreator 부분에서만 생성코드를 넣는다. )
②동일한 인터페이스 구현으로 새로운 객체가 추가되더라도 소스의 수정의 거의 없다. ( 생성 부분의 수정과 신규 클래스의 추가 정도 )
③객체를 여러군데에서 생성을 각자하면 동일한 생성을 보장 못하지만, 한군데에서 관리하게 되면 동일한 생성을 보장한다.
-연관된 객체들을 생성을 할때 실수로 다른종류의 클래스가 생성이 되는것을 방지한다.
-어플리케이션에서 GUI타입이 여러종류일때, 선택에 따라서 동일한 모양의 GUI타입으로 설정이 된다.
4. 소스
using System; namespace DoFactory.GangOfFour.Abstract.Structural { /// <summary> /// MainApp startup class for Structural /// Abstract Factory Design Pattern. /// </summary> class MainApp { /// <summary> /// Entry point into console application. /// </summary> public static void Main() { // Abstract factory #1 AbstractFactory factory1 = new ConcreteFactory1(); Client client1 = new Client(factory1); client1.Run(); // Abstract factory #2 AbstractFactory factory2 = new ConcreteFactory2(); Client client2 = new Client(factory2); client2.Run(); // Wait for user input Console.ReadKey(); } } /// <summary> /// The 'AbstractFactory' abstract class /// </summary> abstract class AbstractFactory { public abstract AbstractProductA CreateProductA(); public abstract AbstractProductB CreateProductB(); } /// <summary> /// The 'ConcreteFactory1' class /// </summary> class ConcreteFactory1 : AbstractFactory { public override AbstractProductA CreateProductA() { return new ProductA1(); } public override AbstractProductB CreateProductB() { return new ProductB1(); } } /// <summary> /// The 'ConcreteFactory2' class /// </summary> class ConcreteFactory2 : AbstractFactory { public override AbstractProductA CreateProductA() { return new ProductA2(); } public override AbstractProductB CreateProductB() { return new ProductB2(); } } /// <summary> /// The 'AbstractProductA' abstract class /// </summary> abstract class AbstractProductA { } /// <summary> /// The 'AbstractProductB' abstract class /// </summary> abstract class AbstractProductB { public abstract void Interact(AbstractProductA a); } /// <summary> /// The 'ProductA1' class /// </summary> class ProductA1 : AbstractProductA { } /// <summary> /// The 'ProductB1' class /// </summary> class ProductB1 : AbstractProductB { public override void Interact(AbstractProductA a) { Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name); } } /// <summary> /// The 'ProductA2' class /// </summary> class ProductA2 : AbstractProductA { } /// <summary> /// The 'ProductB2' class /// </summary> class ProductB2 : AbstractProductB { public override void Interact(AbstractProductA a) { Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name); } } /// <summary> /// The 'Client' class. Interaction environment for the products. /// </summary> class Client { private AbstractProductA _abstractProductA; private AbstractProductB _abstractProductB; // Constructor public Client(AbstractFactory factory) { _abstractProductB = factory.CreateProductB(); _abstractProductA = factory.CreateProductA(); } public void Run() { _abstractProductB.Interact(_abstractProductA); } } }
-Client 클래스의 생성자에서 AbstractFactory 객체를 받아서 실제 AbstractProductA, AbstractProductB 를 생성한다.
5.실행결과
ProductB1 interacts with ProductA1
ProductB2 interacts with ProductA2
<실제 적용>
1. UML Diagram
2. 사용 용도 및 장점
-사용자가 선택한 종족(테란, 프로토스, 저그 )에 따라서 생성할 수 있는 빌딩들을 설정할 수 있다.
-보통 종족마다 비슷한 종류의 기능을 하는 건물들이 70~80프로는 비슷하다. 이때 추상팩토리 패턴을 이용해서 구현이 가능하다.
-GUI 설정(지도위에 테두리, 마우스 포인터 등등)도 AbstractProduct로 하나더 생성해서 추가하면 된다.
-추상팩토리를 이용하면 테란이 인구확장으로 파일런을 생성하는 경우는 없앨수 있다.
3. 소스
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace AbstractFactory { class Program { static void Main(string[] args) { Race _race1 = new Terran(); Game _game1 = new Game(_race1); _game1.Show(); Race _race2 = new Protoss(); Game _game2 = new Game(_race2); _game2.Show(); Console.ReadKey(); } #region 추상 팩토리 설정 abstract class Race { public abstract MaincenterBuilding CreateMaincenterBuilding(); public abstract PopulationBuilding CreatePopulationBuilding(); } class Terran : Race { public override MaincenterBuilding CreateMaincenterBuilding() { return new CommandCenter(); } public override PopulationBuilding CreatePopulationBuilding() { return new SupplyDepot(); } } class Protoss : Race { public override MaincenterBuilding CreateMaincenterBuilding() { return new Nexus(); } public override PopulationBuilding CreatePopulationBuilding() { return new Pylon(); } } #endregion #region 추상 Product 클래스 생성 abstract class MaincenterBuilding { } abstract class PopulationBuilding { public abstract void Interact(MaincenterBuilding a); } #endregion #region Product 클래스 생성 class CommandCenter : MaincenterBuilding { } class SupplyDepot : PopulationBuilding { public override void Interact(MaincenterBuilding a) { Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name); } } class Nexus : MaincenterBuilding { } class Pylon : PopulationBuilding { public override void Interact(MaincenterBuilding a) { Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name); } } #endregion class Game { private MaincenterBuilding _maincenterBuilding; private PopulationBuilding _populationBuilding; public Game(Race _race) { _maincenterBuilding = _race.CreateMaincenterBuilding(); _populationBuilding = _race.CreatePopulationBuilding(); } public void Show() { _populationBuilding.Interact(_maincenterBuilding); } } } }
4. 결과
5. 피드백
-Factory Method 패턴과 비슷하지만 그것과는 다르게 연관된 클래스들을(family) 생성한다.
-위의 다이어그램에서 저그가 추가될 시에는 클래스 3개가 추가되고 Game에서 해당 저그를 생성해서 사용해주면 된다.
[참조]
-Professional VB.NET 디자인 패턴
-http://www.dofactory.com
'프로젝트 설계 > 디자인 패턴' 카테고리의 다른 글
5. Decorator Pattern ( 데코레이터 / 장식자 패턴 C# ) (1) | 2012.08.29 |
---|---|
4. Adapter Pattern ( 어댑터 / 적응자 패턴 C# ) (2) | 2012.08.28 |
2. Factory Method Pattern ( 팩토리 매소드 패턴 C# ) (14) | 2012.08.22 |
1. Singleton Pattern(싱글턴 패턴 C#) (17) | 2011.12.15 |
GOF 23개 디자인 패턴 분석 (2) | 2011.12.14 |