2024. 10. 2. 23:32ㆍDesign Pattern
C# 디자인 패턴: Factory 패턴 및 추상 팩토리 패턴
소프트웨어 개발에서 객체를 생성하는 방식은 코드의 유연성 및 유지보수에 큰 영향을 미칩니다.
Factory 패턴과 추상 팩토리 패턴은 객체 생성 과정을 캡슐화하여 객체 생성 로직을 유연하게 관리할 수 있게 해주는 생성 패턴(Creational Patterns) 중 하나입니다.
이 글에서는 두 패턴의 개념과 차이점을 설명하고, 사용 예시를 통해 구체적인 구현 방법을 살펴보겠습니다.
Factory 패턴 (Factory Method Pattern)
정의
Factory 패턴은 객체 생성을 위한 인터페이스를 제공하되, 어떤 클래스의 인스턴스를 생성할지는 서브클래스에서 결정하는 패턴입니다. 즉, 객체 생성의 책임을 서브클래스로 넘기며, 이를 통해 코드의 유연성을 확보할 수 있습니다.
주요 특징
- 객체 생성을 캡슐화하여, 객체 생성 로직을 변경해도 코드의 다른 부분에 영향을 주지 않음.
- 클라이언트는 객체 생성 방식에 의존하지 않고, 인터페이스에 의존함.
- 클래스 간의 결합도를 낮출 수 있어, 확장성과 유지보수성이 높아짐.
사용 예시
// Product 인터페이스
public interface IProduct
{
void Operate();
}
// 구체적인 Product 클래스
public class ConcreteProductA : IProduct
{
public void Operate()
{
Console.WriteLine("ConcreteProductA is operating.");
}
}
public class ConcreteProductB : IProduct
{
public void Operate()
{
Console.WriteLine("ConcreteProductB is operating.");
}
}
// Factory 클래스
public abstract class Creator
{
public abstract IProduct FactoryMethod();
public void SomeOperation()
{
var product = FactoryMethod();
product.Operate();
}
}
// ConcreteCreator 클래스
public class ConcreteCreatorA : Creator
{
public override IProduct FactoryMethod()
{
return new ConcreteProductA();
}
}
public class ConcreteCreatorB : Creator
{
public override IProduct FactoryMethod()
{
return new ConcreteProductB();
}
}
위 코드에서는 Creator 클래스가 FactoryMethod라는 메서드를 통해 객체 생성의 책임을 서브클래스에 넘기고 있습니다. 구체적인 객체는 ConcreteCreatorA와 ConcreteCreatorB 클래스에서 결정됩니다.
장점
- 객체 생성 로직을 한 곳에서 관리하여 중복된 코드를 줄일 수 있습니다.
- 유연성이 높아져 객체 생성 방식을 쉽게 변경하거나 확장할 수 있습니다.
추상 팩토리 패턴 (Abstract Factory Pattern)
정의
추상 팩토리 패턴은 관련된 객체들을 그룹으로 생성하는 인터페이스를 제공합니다. 구체적인 클래스를 지정하지 않고, 서로 관련 있는 객체들의 집합을 생성할 수 있는 패턴입니다. 즉, 여러 객체를 생성하는 데 있어 일관된 방식을 제공하고, 구체적인 클래스에 대한 의존성을 제거할 수 있습니다.
주요 특징
- 다양한 객체 그룹을 생성할 수 있습니다.
- 구체적인 클래스에 의존하지 않고, 관련 있는 객체들 간의 일관성을 유지합니다.
- 시스템을 확장할 때 유연성을 제공합니다.
사용 예시
// AbstractFactory 인터페이스
public interface IAbstractFactory
{
IProductA CreateProductA();
IProductB CreateProductB();
}
// 구체적인 ProductA 및 ProductB
public interface IProductA
{
void Operate();
}
public interface IProductB
{
void Operate();
}
public class ConcreteProductA1 : IProductA
{
public void Operate()
{
Console.WriteLine("ConcreteProductA1 is operating.");
}
}
public class ConcreteProductA2 : IProductA
{
public void Operate()
{
Console.WriteLine("ConcreteProductA2 is operating.");
}
}
public class ConcreteProductB1 : IProductB
{
public void Operate()
{
Console.WriteLine("ConcreteProductB1 is operating.");
}
}
public class ConcreteProductB2 : IProductB
{
public void Operate()
{
Console.WriteLine("ConcreteProductB2 is operating.");
}
}
// ConcreteFactory 클래스
public class ConcreteFactory1 : IAbstractFactory
{
public IProductA CreateProductA()
{
return new ConcreteProductA1();
}
public IProductB CreateProductB()
{
return new ConcreteProductB1();
}
}
public class ConcreteFactory2 : IAbstractFactory
{
public IProductA CreateProductA()
{
return new ConcreteProductA2();
}
public IProductB CreateProductB()
{
return new ConcreteProductB2();
}
}
위 코드에서는 IAbstractFactory 인터페이스가 CreateProductA와 CreateProductB 메서드를 통해 관련 있는 객체들을 생성합니다. ConcreteFactory1과 ConcreteFactory2는 서로 다른 그룹의 객체를 생성하지만, 일관된 인터페이스를 통해 생성됩니다.
장점
- 여러 관련 객체들의 생성 과정을 관리하고 일관성을 유지합니다.
- 구체적인 클래스에 대한 의존성을 제거하여 확장과 변경이 용이합니다.
Factory 패턴과 추상 팩토리 패턴의 차이점
Factory 패턴추상 팩토리 패턴
한 종류의 객체를 생성하기 위한 패턴 | 관련된 여러 객체 그룹을 생성할 수 있는 패턴 |
객체 생성의 책임을 서브클래스로 넘김 | 관련 있는 객체들의 생성을 캡슐화하고, 여러 객체를 일관되게 생성할 수 있음 |
하나의 객체만 생성하는 데 사용됨 | 서로 관련된 여러 객체들을 그룹으로 생성해야 할 때 사용됨 |
클래스 간의 결합도를 줄이고 객체 생성을 유연하게 만듦 | 여러 제품군을 사용하는 시스템에서 제품 간의 일관성을 유지하는 데 도움을 줌 |
Factory 패턴과 추상 팩토리 패턴은 객체 생성에 관련된 문제를 해결하는 데 매우 유용한 패턴입니다.
Factory 패턴은 특정 객체를 생성하는 책임을 서브클래스로 넘기는 데 주로 사용되며, 추상 팩토리 패턴은 관련 있는 객체들의 그룹을 생성하고, 일관성을 유지해야 할 때 적합합니다. 두 패턴 모두 유연한 코드 작성과 유지보수성을 높이는 데 기여하며, 확장 가능한 소프트웨어 아키텍처를 구축하는 데 중요한 역할을 합니다.
'Design Pattern' 카테고리의 다른 글
빌더(Builder) 패턴 (0) | 2024.10.10 |
---|---|
옵저버(Observer) 패턴 (5) | 2024.10.03 |
디자인 패턴의 분류 (생성 패턴, 구조 패턴, 행위 패턴) (0) | 2024.10.01 |
SOLID 원칙: 객체 지향 설계의 5가지 핵심 원칙 (0) | 2024.10.01 |
의존성 주입(Dependency Injection) (0) | 2024.10.01 |