C#에서 **생성 패턴(Creational Patterns)**은 객체의 생성 방식을 정의하고 캡슐화하여 코드의 유연성과 유지보수성을 높이는 디자인 패턴입니다. 대표적인 생성 패턴으로는 다음과 같은 다섯 가지가 있습니다.
Singleton (싱글톤 패턴)
- 목적: 클래스의 인스턴스를 하나만 생성하고 전역적으로 접근할 수 있도록 보장
- 활용 예시: 데이터베이스 연결, 설정 관리, 로깅 시스템
public class Singleton
{
private static Singleton? _instance;
private static readonly object _lock = new object();
private Singleton() { } // 생성자 비공개
public static Singleton Instance
{
get
{
lock (_lock)
{
return _instance ??= new Singleton();
}
}
}
}
Factory Method (팩토리 메서드 패턴)
- 목적: 객체 생성을 서브클래스에서 담당하도록 위임하여 확장성을 높임
- 활용 예시: 다양한 타입의 객체 생성 (예: 문서 생성기, UI 컨트롤러)
public abstract class Product
{
public abstract void Use();
}
public class ConcreteProductA : Product
{
public override void Use() => Console.WriteLine("Product A 사용");
}
public class ConcreteProductB : Product
{
public override void Use() => Console.WriteLine("Product B 사용");
}
public abstract class Creator
{
public abstract Product FactoryMethod();
}
public class ConcreteCreatorA : Creator
{
public override Product FactoryMethod() => new ConcreteProductA();
}
public class ConcreteCreatorB : Creator
{
public override Product FactoryMethod() => new ConcreteProductB();
}
Abstract Factory (추상 팩토리 패턴)
- 목적: 관련된 객체들의 집합을 생성할 때, 구체적인 클래스를 지정하지 않고 생성
- 활용 예시: OS별 UI 컴포넌트 생성 (Windows, macOS, Linux 등)
// 1. 추상 제품군 정의
public interface IButton { void Render(); }
public interface ITextBox { void Render(); }
// 2. 구체적인 제품군 정의 (Windows 스타일)
public class WindowsButton : IButton
{
public void Render() => Console.WriteLine("Windows 버튼 렌더링");
}
public class WindowsTextBox : ITextBox
{
public void Render() => Console.WriteLine("Windows 텍스트박스 렌더링");
}
// 3. 구체적인 제품군 정의 (Mac 스타일)
public class MacButton : IButton
{
public void Render() => Console.WriteLine("Mac 버튼 렌더링");
}
public class MacTextBox : ITextBox
{
public void Render() => Console.WriteLine("Mac 텍스트박스 렌더링");
}
// 4. 추상 팩토리 정의
public interface IGUIFactory
{
IButton CreateButton();
ITextBox CreateTextBox();
}
// 5. 구체적인 팩토리 정의
public class WindowsFactory : IGUIFactory
{
public IButton CreateButton() => new WindowsButton();
public ITextBox CreateTextBox() => new WindowsTextBox();
}
public class MacFactory : IGUIFactory
{
public IButton CreateButton() => new MacButton();
public ITextBox CreateTextBox() => new MacTextBox();
}
Builder (빌더 패턴)
- 목적: 객체 생성을 단계별로 진행하며, 최종적으로 완전한 객체를 생성
- 활용 예시: 복잡한 객체(예: HTML 문서, 게임 캐릭터) 생성
public class Car
{
public string Engine { get; set; }
public int Seats { get; set; }
public bool HasGPS { get; set; }
public void ShowInfo()
{
Console.WriteLine($"Engine: {Engine}, Seats: {Seats}, GPS: {HasGPS}");
}
}
// 빌더 인터페이스
public interface ICarBuilder
{
ICarBuilder SetEngine(string engine);
ICarBuilder SetSeats(int seats);
ICarBuilder SetGPS(bool hasGPS);
Car Build();
}
// 빌더 구현
public class CarBuilder : ICarBuilder
{
private Car _car = new Car();
public ICarBuilder SetEngine(string engine)
{
_car.Engine = engine;
return this;
}
public ICarBuilder SetSeats(int seats)
{
_car.Seats = seats;
return this;
}
public ICarBuilder SetGPS(bool hasGPS)
{
_car.HasGPS = hasGPS;
return this;
}
public Car Build() => _car;
}
// 빌더 사용 예시
var builder = new CarBuilder();
Car car = builder.SetEngine("V8").SetSeats(4).SetGPS(true).Build();
car.ShowInfo();
Prototype (프로토타입 패턴)
- 목적: 기존 객체를 복사하여 새로운 객체를 생성
- 활용 예시: 게임 캐릭터 복사, 설정 복제
public class Prototype : ICloneable
{
public string Name { get; set; }
public int Age { get; set; }
public Prototype(string name, int age)
{
Name = name;
Age = age;
}
public object Clone() => new Prototype(Name, Age);
public void ShowInfo() => Console.WriteLine($"Name: {Name}, Age: {Age}");
}
// 사용 예시
var original = new Prototype("홍길동", 30);
var copy = (Prototype)original.Clone();
copy.ShowInfo(); // Name: 홍길동, Age: 30
정리
패턴 | 설명 | 활용 예시 |
Singleton | 단 하나의 인스턴스를 유지 | 설정 관리, 로깅 시스템 |
Factory Method | 객체 생성을 서브클래스에서 결정 | UI 컨트롤러, 데이터베이스 연결 |
Abstract Factory | 관련된 객체의 집합을 생성 | OS별 UI 컴포넌트 |
Builder | 복잡한 객체를 단계별로 생성 | HTML 생성기, 게임 캐릭터 설정 |
Prototype | 기존 객체를 복제하여 새 객체 생성 | 게임 캐릭터 복사, 설정 복제 |
이처럼 생성 패턴을 적절히 활용하면 코드의 유연성과 유지보수성을 향상시킬 수 있습니다. 🚀