빌더(Builder) 패턴
2024. 10. 10. 01:02ㆍDesign Pattern
디자인 패턴: 빌더(Builder) 패턴
빌더 패턴(Builder Pattern)은 복잡한 객체의 생성 과정을 단계별로 분리하여, 같은 생성 절차에서 서로 다른 표현을 만들 수 있게 하는 생성 패턴(Creational Patterns) 중 하나입니다. 이 패턴은 객체를 단계별로 구성하거나 점진적으로 구성해야 할 때 유용하게 사용됩니다. 특히, 복잡한 객체 생성 로직을 클라이언트 코드와 분리하여 가독성과 유지보수성을 높이는 데 기여합니다.
빌더 패턴의 개념
빌더 패턴은 객체를 생성하는 데 필요한 과정을 여러 단계로 나누고, 그 단계를 순차적으로 실행하는 구조를 따릅니다. 객체를 단계별로 구성한 후 마지막 단계에서 완성된 객체를 반환합니다. 이렇게 하면 객체 생성 과정이 복잡해지더라도 각 단계를 세분화하여 관리할 수 있습니다.
주요 구성 요소
- Product (제품)
- 빌더가 생성하는 복합 객체입니다. 여러 단계에 걸쳐 빌더에 의해 생성됩니다.
- Builder (빌더)
- 제품의 구성 단계를 정의하는 인터페이스입니다. 각 단계에서 필요한 구성 요소를 정의하고, 이를 통해 객체를 점진적으로 생성합니다.
- ConcreteBuilder (구체적인 빌더)
- 빌더 인터페이스를 구현한 구체적인 빌더입니다. 특정 제품을 생성하는 데 필요한 단계별 구현을 제공합니다.
- Director (감독자)
- 빌더를 통해 객체를 생성하는 절차를 제어합니다. 감독자는 빌더에게 객체를 생성하는 순서를 지시하며, 최종 결과물인 객체를 반환받습니다.
빌더 패턴 구현 예시
1. Product 클래스
// Product: 빌더 패턴으로 생성될 객체
public class House
{
public string Walls { get; set; }
public string Roof { get; set; }
public string Foundation { get; set; }
public override string ToString()
{
return $"House with {Foundation}, {Walls}, and {Roof}.";
}
}
2. Builder 인터페이스
// Builder: House의 구성 단계 정의
public interface IHouseBuilder
{
void BuildFoundation();
void BuildWalls();
void BuildRoof();
House GetHouse();
}
3. ConcreteBuilder 클래스
// ConcreteBuilder: 구체적인 House 빌더
public class ConcreteHouseBuilder : IHouseBuilder
{
private House _house = new House();
public void BuildFoundation()
{
_house.Foundation = "Concrete Foundation";
}
public void BuildWalls()
{
_house.Walls = "Brick Walls";
}
public void BuildRoof()
{
_house.Roof = "Tile Roof";
}
public House GetHouse()
{
return _house;
}
}
4. Director 클래스
// Director: 빌더를 통해 House 생성 과정 제어
public class HouseDirector
{
private IHouseBuilder _builder;
public HouseDirector(IHouseBuilder builder)
{
_builder = builder;
}
public void ConstructHouse()
{
_builder.BuildFoundation();
_builder.BuildWalls();
_builder.BuildRoof();
}
}
5. 빌더 패턴 사용 예시
class Program
{
static void Main(string[] args)
{
// ConcreteBuilder 사용
IHouseBuilder builder = new ConcreteHouseBuilder();
HouseDirector director = new HouseDirector(builder);
// House 생성
director.ConstructHouse();
House house = builder.GetHouse();
// 생성된 House 출력
Console.WriteLine(house);
}
}
출력 결과:
House with Concrete Foundation, Brick Walls, and Tile Roof.
빌더 패턴의 장점
- 복잡한 객체 생성 과정 분리
- 객체를 생성하는 코드를 세분화하여 단계별로 관리할 수 있습니다. 각 구성 요소를 독립적으로 생성하고 조합할 수 있어, 복잡한 객체도 쉽게 만들 수 있습니다.
- 유연성
- 빌더를 통해 동일한 생성 절차에서 다양한 표현의 객체를 생성할 수 있습니다. 객체 생성에 대한 제어권이 명확해지고, 필요에 따라 객체 구성을 쉽게 변경할 수 있습니다.
- 가독성 향상
- 생성 과정을 단계별로 나누어 코드가 직관적이고 읽기 쉽게 됩니다. 특히, 매개변수가 많은 객체 생성 시 빌더 패턴을 사용하면 코드의 복잡도를 줄일 수 있습니다.
빌더 패턴의 단점
- 복잡한 구조
- 빌더 패턴 자체가 다수의 클래스(Builder, ConcreteBuilder, Director 등)를 요구하므로, 비교적 간단한 객체를 생성하는 경우에는 오히려 불필요하게 복잡해질 수 있습니다.
- 객체 생성 비용 증가
- 객체 생성 절차가 세분화되면서 빌더 객체를 추가로 생성하고 관리해야 하기 때문에, 간단한 객체 생성에는 성능상 이점이 크지 않을 수 있습니다.
빌더 패턴의 사용 사례
- 복잡한 객체 생성
- 매개변수가 많은 객체를 생성할 때, 생성자의 매개변수를 잘못 전달할 위험을 줄이고 가독성을 높일 수 있습니다. 예를 들어, 복잡한 GUI 구성 요소나 다수의 옵션을 가진 객체 생성 시 유용합니다.
- 객체의 다양한 표현 필요
- 동일한 생성 절차에서 서로 다른 표현을 가진 객체를 생성해야 할 때, 빌더 패턴은 유용하게 사용됩니다. 예를 들어, 게임 개발에서 다양한 캐릭터나 아이템을 생성할 때, 빌더 패턴을 활용할 수 있습니다.
빌더 패턴은 복잡한 객체를 단계적으로 생성할 수 있도록 도와주는 유용한 디자인 패턴입니다.
각 단계별로 객체를 구성하고, 필요에 따라 다양한 표현의 객체를 생성할 수 있어 유연성과 확장성을 제공합니다. 다만 간단한 객체를 생성하는 데는 오히려 불필요한 복잡성을 추가할 수 있으므로, 적절한 상황에서 활용하는 것이 중요합니다.
'Design Pattern' 카테고리의 다른 글
데코레이터(Decorator) 패턴 (1) | 2024.10.14 |
---|---|
어댑터(Adapter) 패턴 (1) | 2024.10.12 |
옵저버(Observer) 패턴 (5) | 2024.10.03 |
Factory 패턴 및 추상 팩토리 패턴 (0) | 2024.10.02 |
디자인 패턴의 분류 (생성 패턴, 구조 패턴, 행위 패턴) (0) | 2024.10.01 |