목차
추상 팩토리(Abstract Factory)
Abstract Factory 패턴은 서로 관련있거나 의존적인 객체들의 그룹을 생성하기 위한 인터페이스를 제공하지만, 구체적으로 어떤 클래스의 인스턴스를 생성할지는 서브클래스가 결정하게 하는 생성 디자인 패턴이다. 즉, 클라이언트는 생성할 객체의 정확한 클래스를 명시하지 않고도 객체를 생성할 수 있다. 이 패턴은 객체 생성에 관련된 로직을 프로그램의 나머지 부분으로부터 분리하며, 코드의 유연성과 재사용성을 높인다.
Abstract Factory 패턴은 생성(Creational) 디자인 패턴에 속한다. 이 패턴은 객체의 생성 과정을 추상화함으로써, 클라이언트가 특정 클래스의 인스턴스에 직접적으로 의존하지 않도록 하여, 시스템의 결합도를 낮추고, 확장성과 유연성을 높이는 데 초점을 맞춘다. 따라서, 객체 생성과 관련된 코드를 시스템의 다른 부분과 분리하고, 동일한 생성 절차를 통해 다양한 타입의 객체를 생성할 수 있게 한다.
어원
"Abstract Factory"라는 이름은 이 패턴이 구체적인 클래스를 명시하지 않고 객체의 생성을 책임지는 추상적인 '공장'을 제공한다는 개념에서 비롯된다. 'Abstract'는 구체적인 클래스에 의존하지 않는 추상화된 접근 방식을, 'Factory'는 객체 생성의 역할을 담당하는 공장이나 생성자를 의미한다. 결국, 이 패턴은 다양한 구현체가 존재할 수 있는 추상화된 인터페이스를 통해 객체를 생성하는 공장들의 집합을 정의한다.
패턴 미적용 예시 코드 (C#)
먼저, Abstract Factory 패턴을 적용하지 않은 경우를 살펴보자. 아래 예시에서는 윈도우와 버튼을 만드는 간단한 예를 들어, 각각의 구체적인 클래스를 직접 생성하고 있다.
Client
│
├── 직접 생성 ──> WindowsButton
│ (IButton 인터페이스 구현)
│
└── 직접 생성 ──> MacButton
(IButton 인터페이스 구현)
// 버튼 인터페이스
public interface IButton
{
void Paint();
}
// 윈도우 인터페이스
public interface IWindow
{
void Render();
}
// 윈도우즈 버튼 구현
public class WindowsButton : IButton
{
public void Paint()
{
Console.WriteLine("Windows 버튼을 그린다.");
}
}
// 맥 버튼 구현
public class MacButton : IButton
{
public void Paint()
{
Console.WriteLine("Mac 버튼을 그린다.");
}
}
// 클라이언트 코드
public class Client
{
public void CreateUI()
{
IButton button = new WindowsButton();
// 직접적으로 WindowsButton 클래스를 참조
button.Paint();
}
}
// 클라이언트 코드 실행
var client = new Client();
client.CreateUI();
패턴 적용 예시 코드 (C#)
Abstract Factory 패턴을 적용하여, 객체 생성을 추상화된 인터페이스를 통해 처리하도록 바꿔보자.
Client
│
└── 사용 ──> IUIFactory <---- Abstract Factory Interface
│
├── 생성 ──> WindowsFactory
│ │
│ └── 생성 ──> WindowsButton
│ (IButton 인터페이스 구현)
│
└── 생성 ──> MacFactory
│
└── 생성 ──> MacButton
(IButton 인터페이스 구현)
// 버튼 인터페이스
public interface IButton
{
void Paint();
}
// UI 팩토리 인터페이스
public interface IUIFactory
{
IButton CreateButton();
}
// 윈도우즈 버튼 구현
public class WindowsButton : IButton
{
public void Paint()
{
Console.WriteLine("Windows 버튼을 그린다.");
}
}
// 맥 버튼 구현
public class MacButton : IButton
{
public void Paint()
{
Console.WriteLine("Mac 버튼을 그린다.");
}
}
// 윈도우즈 UI 팩토리 구현
public class WindowsFactory : IUIFactory
{
public IButton CreateButton()
{
return new WindowsButton(); // 윈도우즈 버튼 생성
}
}
// 맥 UI 팩토리 구현
public class MacFactory : IUIFactory
{
public IButton CreateButton()
{
return new MacButton(); // 맥 버튼 생성
}
}
// 클라이언트 코드
public class Client
{
private IButton _button;
public Client(IUIFactory factory)
{
_button = factory.CreateButton(); // 팩토리를 통해 버튼 생성
}
public void CreateUI()
{
_button.Paint(); // 생성된 버튼을 화면에 출력
}
}
// 애플리케이션 구성
class Program
{
static void Main(string[] args)
{
IUIFactory factory;
// 환경에 따라 적절한 팩토리 인스턴스를 선택
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
factory = new WindowsFactory();
}
else
{
factory = new MacFactory();
}
// 클라이언트 코드 실행
var client = new Client(factory);
client.CreateUI();
}
}
위 코드는 Abstract Factory 패턴을 적용한 예시로, 클라이언트는 구체적인 팩토리(WindowsFactory 혹은 MacFactory)를 통해 필요한 객체(WindowsButton 혹은 MacButton)를 생성한다. 이 방식을 통해, 클라이언트는 생성해야 할 객체의 구체적인 클래스를 몰라도 되며, 시스템의 다른 부분에 영향을 주지 않고 새로운 팩토리나 프로덕트 클래스를 쉽게 추가할 수 있다. 이는 코드의 유연성과 확장성을 크게 향상시키는 핵심 이점이다.
Abstract Factory vs Simple Factory
Abstract Factory 패턴과 Simple Factory 패턴은 모두 생성 패턴에 속하지만, 사용 목적과 적용 시나리오에서 차이가 있다.
Abstract Factory 패턴
Abstract Factory 패턴은 서로 관련있거나 의존적인 객체의 그룹을 생성하기 위한 인터페이스를 제공한다. 이 패턴은 구체적인 클래스에 의존하지 않고 인터페이스를 통해 객체의 그룹을 생성하고, 구체적인 팩토리는 이 인터페이스를 구현하여 객체 그룹의 구체적인 구현을 제공한다. Abstract Factory 패턴은 시스템을 팩토리의 구체적인 구현으로부터 독립적으로 만들고자 할 때 유용하며, 특히 다양한 구현을 쉽게 교체하거나, 다양한 환경에서 일관된 방식으로 객체를 생성해야 할 때 적합하다.
Simple Factory 패턴
반면, Simple Factory 패턴은 객체 생성을 위한 인터페이스를 정의하지 않는다. 대신, Simple Factory는 단순히 클라이언트의 요청에 따라 인스턴스를 생성하고 반환하는 역할을 한다. 이 패턴은 특정 기준(예: 입력 파라미터)에 따라 다른 클래스의 인스턴스를 생성해야 할 때 유용하다. Simple Factory는 구현이 간단하며, 주로 단일 메소드로 구성된다. 하지만, Abstract Factory 패턴처럼 다양한 객체 그룹을 생성하는 데에는 적합하지 않다.
차이점 요약
- 목적의 차이: Abstract Factory는 관련 있는 객체의 그룹을 생성하는 인터페이스를 제공하는 반면, Simple Factory는 단순히 요청받은 타입의 객체를 생성하고 반환한다.
- 복잡성: Abstract Factory는 다양한 객체 그룹을 생성할 수 있는 복잡한 구조를 가지고 있으며, 여러 구체적인 팩토리 클래스가 필요하다. 반면, Simple Factory는 구현이 단순하며 주로 하나의 메소드로 구성된다.
- 사용 시나리오: Abstract Factory는 시스템이 여러 버전이나 변형에 걸쳐 일관된 방식으로 객체 그룹을 생성해야 할 때 사용된다. 반면, Simple Factory는 특정 조건에 따라 개별 객체를 생성해야 할 때 사용된다.
- 유연성: Abstract Factory는 다양한 팩토리 구현을 쉽게 교체할 수 있어 시스템의 유연성을 높일 수 있으나, Simple Factory는 보다 제한적인 상황에 적합하다.
이러한 차이점들은 각 패턴이 적합한 상황과 사용되어야 하는 컨텍스트를 결정하는 데 중요한 역할을 한다. 따라서, 소프트웨어 개발 프로젝트에서 요구사항과 문제 상황을 정확히 파악한 후 적절한 디자인 패턴을 선택하는 것이 중요하다.
'컴퓨터 과학 > 디자인패턴' 카테고리의 다른 글
[디자인패턴] 생성 패턴(5) : 프로토타입(Prototype) (0) | 2024.03.24 |
---|---|
[디자인패턴] 생성 패턴(4) : 빌더(Builder) (0) | 2024.03.24 |
[디자인패턴] 생성 패턴(3) : 팩토리 메서드(Factory Method) (0) | 2024.03.24 |
[디자인패턴] 생성 패턴(1) : 심플 팩토리(Simple Factory) (0) | 2024.03.24 |
[디자인 패턴] 디자인 패턴의 역사와 종류 (0) | 2024.03.24 |