개요
빌더 패턴은 복잡한 객체의 생성 과정을 그 표현과 분리하는 생성형 디자인 패턴입니다. 동일한 생성 과정으로 다양한 표현의 객체를 만들 수 있으며, 단계별로 복잡한 객체를 구성할 수 있습니다.
구성 요소
빌더 패턴은 다음과 같은 역할로 구성됩니다:
- 제품(Product): 생성될 복잡한 객체
- 추상 빌더(Builder): 제품의 각 부분을 생성하는 인터페이스 정의
- 구체적 빌더(ConcreteBuilder): Builder 인터페이스를 구현하여 각 부분 구성
- 지휘자(Director): Builder 인터페이스를 사용하는 객체 생성
구현 예제
다양한 유형의 컴퓨터(게임용, 사무용)를 생성하는 애플리케이션을 가정합니다.
제품 클래스
public class 컴퓨터시스템
{
public string 중앙처리장치 { get; set; }
public string 그래픽카드 { get; set; }
public string 메모리 { get; set; }
public string 저장장치 { get; set; }
public override string ToString()
{
return $"CPU: {중앙처리장치}, GPU: {그래픽카드}, RAM: {메모리}, Storage: {저장장치}";
}
}
추상 빌더 인터페이스
public interface I컴퓨터빌더
{
void CPU설정();
void GPU설정();
void RAM설정();
void 저장장치설정();
컴퓨터시스템 컴퓨터얻기();
}
구체적 빌더 구현
public class 게임용컴퓨터빌더 : I컴퓨터빌더
{
private 컴퓨터시스템 _컴퓨터 = new 컴퓨터시스템();
public void CPU설정()
{
_컴퓨터.중앙처리장치 = "고성능 CPU";
}
public void GPU설정()
{
_컴퓨터.그래픽카드 = "고성능 그래픽카드";
}
public void RAM설정()
{
_컴퓨터.메모리 = "16GB RAM";
}
public void 저장장치설정()
{
_컴퓨터.저장장치 = "1TB SSD";
}
public 컴퓨터시스템 컴퓨터얻기()
{
return _컴퓨터;
}
}
public class 사무용컴퓨터빌더 : I컴퓨터빌더
{
private 컴퓨터시스템 _컴퓨터 = new 컴퓨터시스템();
public void CPU설정()
{
_컴퓨터.중앙처리장치 = "중급 CPU";
}
public void GPU설정()
{
_컴퓨터.그래픽카드 = "내장 그래픽";
}
public void RAM설정()
{
_컴퓨터.메모리 = "8GB RAM";
}
public void 저장장치설정()
{
_컴퓨터.저장장치 = "512GB SSD";
}
public 컴퓨터시스템 컴퓨터얻기()
{
return _컴퓨터;
}
}
지휘자 클래스
public class 컴퓨터생성관리자
{
public void 컴퓨터생성(I컴퓨터빌더 빌더)
{
빌더.CPU설정();
빌더.GPU설정();
빌더.RAM설정();
빌더.저장장치설정();
}
}
클라이언트 코드
class 프로그램
{
static void Main(string[] 인자들)
{
컴퓨터생성관리자 관리자 = new 컴퓨터생성관리자();
// 게임용 컴퓨터 생성
I컴퓨터빌더 게임빌더 = new 게임용컴퓨터빌더();
관리자.컴퓨터생성(게임빌더);
컴퓨터시스템 게임컴퓨터 = 게임빌더.컴퓨터얻기();
Console.WriteLine("게임용 컴퓨터: " + 게임컴퓨터);
// 사무용 컴퓨터 생성
I컴퓨터빌더 사무빌더 = new 사무용컴퓨터빌더();
관리자.컴퓨터생성(사무빌더);
컴퓨터시스템 사무컴퓨터 = 사무빌더.컴퓨터얻기();
Console.WriteLine("사무용 컴퓨터: " + 사무컴퓨터);
}
}
적용 상황
빌더 패턴은 다음과 같은 경우에 적합합니다:
- 복잡한 객체 생성 알고리즘이 객체의 구성 요소 및 조립 방식과 독립적이어야 할 때
- 생성 과정에서 객체의 다양한 표현이 허용되어야 할 때
장단점
장점
- 생성 과정의 명확한 제어: 단계별 객체 생성으로 프로세스 투명성 향상
- 유연성: 다양한 요구사항에 맞게 객체 내부 표현 변경 가능
단점
- 코드 복잡성 증가: 각 구체적 빌더가 인터페이스를 구현해야 하므로 코드량 증가