목차
추상 팩토리 패턴
추상 팩토리 패턴(Abstract Factory Pattern)은 관련된 객체의 그룹을 생성하기 위한 인터페이스를 제공하는 디자인 패턴입니다.
이 패턴은 객체의 생성을 구체적인 클래스로부터 분리함으로써, 클라이언트 코드가 시스템의 구체적인 구현과 독립적으로 동작할 수 있도록 합니다.
추상 팩토리 패턴의 주요 목적은 제품군 생성입니다. 이에 따라 이전 패턴들을 발전시킨다면, 추상 팩토리 패턴이 될 수 있습니다.
•
제품군 생성 : 서로 관련된 여러 객체를 생성하는 일관된 방법을 제공합니다.
심플 팩토리, 팩토리 메소드, 추상 팩토리 패턴 공통정, 차이점
1.
심플 팩토리 패턴 (Simple Factory Pattern)
•
공통점 : 객체 생성을 캡슐화하고, 클라이언트 코드와 생성되는 객체를 분리합니다.
•
차이점 : 이 패턴은 팩토리 클래스 내에서 조건에 따라 인스턴스를 생성합니다. 클라이언트는 팩토리 클래스에 요청을 보내어 필요한 객체를 받습니다. 심플 팩토리는 다형성을 활용하지만 상속이나 인터페이스를 사용하지 않습니다.
2.
팩토리 메소드 패턴 (Factory Method Pattern)
•
공통점 : 객체 생성을 캡슐화하고, 클라이언트 코드와 생성되는 객체를 분리합니다.
•
차이점 : 이 패턴은 추상 클래스 또는 인터페이스를 사용하여 객체 생성을 서브 클래스에 위임합니다. 클라이언트는 추상 인터페이스를 통해 객체를 요청하고, 실제 생성되는 객체의 타입은 서브클래스에서 결정됩니다. 이는 상속을 기반으로 한 확장에 적합합니다.
3.
추상 팩토리 패턴 (Abstract Factory Pattern)
•
공통점 : 객체 생성을 캡슐화하고, 클라이언트 코드와 생성되는 객체를 분리합니다.
•
차이점 : 추상 팩토리 패턴은 여러 종류의 관련있는 또는 의존적인 객체들을 생성하기 위한 인터페이스를 제공합니다. 이 패턴은 서로 다른 팩토리 클래스를 생성하여, 각각 다른 종류의 객체 그룹을 생성할 수 있게 합니다. 이 패턴은 서로 관련 있는 여러 객체들을 일관된 방식으로 생성할 때 유용합니다.
추상 팩토리 패턴의 장,단점
장점
•
유연성과 확장성 : 새로운 제품군을 추가하기 위해 기존 코드를 변경할 필요 없이, 새로운 구체적인 팩토리 클래스를 추가하기만 하면 됩니다.
•
상호 교환 가능성 : 클라이언트 코드 변경 없이 다양한 제품군을 사용할 수 있습니다.
•
제품 사양의 일관성: 하나의 팩토리는 일관된 제품군을 생성함으로써 제품 간의 호환성을 보장합니다.
단점
•
복잡성 증가 : 많은 클래스와 인터페이스를 도입함으로써 시스템의 전반적인 복잡성이 증가할 수 있습니다.
•
유연성 제한 : 새로운 종류의 제품을 추가하기 위해서는 팩토리 인터페이스를 변경해야 하므로, 일단 정의되면 확장하기 어려울 수 있습니다
추상 팩토리 패턴의 구조
1.
추상 팩토리(Abstract Factory) : 관련된 객체 그룹을 생성하는 메소드를 정의합니다.
2.
구체적 팩토리(Concrete Factory) : 추상 팩토리에 정의된 메소드를 구현하여 특정 제품군을 생성합니다.
3.
추상 제품(Abstract Product) : 생성될 제품군의 객체들이 구현해야 하는 인터페이스를 정의합니다.
4.
구체적 제품(Concrete Product ): 추상 제품의 인터페이스를 구현하는 실제 제품 클래스입니다.
5.
클라이언트(Client) : 추상 팩토리와 추상 제품의 인터페이스를 사용하여 작업을 수행합니다.
추상 팩토리 패턴의 UML
아래는 추상 팩토리 패턴 UML입니다.
추상 팩토리 패턴의 구현
추상 팩토리 패턴의 간단한 구현은 실제 유니티에서 사용할 법한 게임 개발 방식으로 설명하겠습니다.
인터페이스 (Interface)
public interface IWeapon {
void Attack();
}
public interface IShield {
void Defend();
}
C#
복사
•
역할 : IWeapon과 IShield 인터페이스는 각각 무기와 방패의 기능을 정의합니다. 이들은 제품군의 일부로, 각각 고유한 동작(공격, 방어)을 정의합니다.
•
목적 : 서로 다른 타입의 무기와 방패들이 이 인터페이스들을 구현함으로써, 클라이언트 코드는 구체적인 제품 타입에 대해 알 필요 없이 이 인터페이스들을 통해 상호작용할 수 있습니다.
구체적인 제품 클래스 (Concrete Product Classes)
public class Sword : IWeapon {
public void Attack() {
Debug.Log("Sword Attack");
}
}
public class MagicShield : IShield {
public void Defend() {
Debug.Log("Magic Shield Defend");
}
}
public class LaserGun : IWeapon {
public void Attack() {
Debug.Log("Laser Gun Attack");
}
}
public class EnergyShield : IShield {
public void Defend() {
Debug.Log("Energy Shield Defend");
}
}
C#
복사
•
역할 : 이 클래스들은 각각의 인터페이스(IWeapon, IShield)를 구현하며, 실제 제품의 구체적인 형태(검, 마법 방패, 레이저 총, 에너지 방패)를 나타냅니다.
•
목적 : 각 클래스는 제품의 특정 타입을 나타내며, 자신만의 Attack 또는 Defend 메소드를 구현하여 독특한 행동을 정의합니다.
추상 팩토리 (Abstract Factory)
public interface IItemFactory {
IWeapon CreateWeapon();
IShield CreateShield();
}
C#
복사
•
역할: IItemFactory 인터페이스는 무기와 방패를 생성하는 메소드를 정의합니다.
•
목적: 이 인터페이스는 서로 관련된 제품군(무기, 방패)을 생성하기 위한 메소드를 제공합니다.
구체적 팩토리 (Concrete Factories)
public class MedievalItemsFactory : IItemFactory {
public IWeapon CreateWeapon() {
return new Sword();
}
public IShield CreateShield() {
return new MagicShield();
}
}
public class FuturisticItemsFactory : IItemFactory {
public IWeapon CreateWeapon() {
return new LaserGun();
}
public IShield CreateShield() {
return new EnergyShield();
}
}
C#
복사
•
역할 : MedievalItemsFactory와 FuturisticItemsFactory는 IItemFactory 인터페이스를 구현합니다. 각 팩토리는 특정 스타일의 무기와 방패(중세 스타일, 미래 스타일)를 생성합니다.
•
목적 : 각 구체적 팩토리는 일관된 스타일의 제품군을 생성합니다.
클라이언트 코드 (Client Code) 실제 사용 방법
// 클라이언트 코드
public class Hero {
private IWeapon _weapon;
private IShield _shield;
public Hero(IItemFactory factory) {
_weapon = factory.CreateWeapon();
_shield = factory.CreateShield();
}
public void Fight() {
_weapon.Attack();
_shield.Defend();
}
}
// 게임 코드
public class Game {
void StartGame() {
// 중세시대 무기를 갖고 있는 영웅을 생성한다.
Hero hero = new Hero(new MedievalItemsFactory());
hero.Fight();
}
}
C#
복사
•
역할 : Hero 클래스는 팩토리를 통해 무기와 방패를 생성하고, Game 클래스는 게임 로직을 구현합니다.
•
목적 : 클라이언트는 추상 팩토리를 통해 필요한 객체를 생성하고, 생성된 객체들을 사용하여 작업을 수행합니다. 이를 통해 클라이언트 코드는 생성되는 객체의 구체적인 타입을 알 필요가 없으며, 다른 스타일의 팩토리를 쉽게 교체할 수 있습니다.