[C# 디자인 패턴] 빌더 디자인 패턴 및 Fluent Builder
- C#
- 2022. 10. 28. 19:49
참고
Builder 디자인 패턴이란?
- 빌더 디자인 패턴은 한 번에 한 단계씩 개체를 생성할 수 있는 생성 디자인 패턴입니다.
- 복잡한 객체를 생성할 때 이 패턴을 사용하는 것은 매우 일반적입니다.
- 이 패턴을 사용하여 단계별로 개체의 다른 부분을 만든 다음 모든 부분을 연결할 수 있습니다.
- 이 패턴이 없으면 객체를 구성하는 데 필요한 모든 매개변수를 제공하는 큰 생성자로 끝낼 수 있습니다.
Builder 디자인 패턴 구현하기
- Builder 디자인 패턴을 어떻게 구현하는지 예제 코드를 작성해 봅니다.
Product 클래스
public class Product
{
public string Name { get; set; }
public double Price { get; set; }
}
- 단일 제품에 대한 몇 가지 기본 데이터를 저장하기 위해 해당 클래스를 사용할 것입니다.
- ProductStockReport 클래스는 HeaderPart, BodyPart, FooterPart 부분으로 구성됩니다.
public class ProductStockReport
{
public string HeaderPart { get; set; }
public string BodyPart { get; set; }
public string FooterPart { get; set; }
public override string ToString() =>
new StringBuilder()
.AppendLine(HeaderPart)
.AppendLine(BodyPart)
.AppendLine(FooterPart)
.ToString();
}
- 위 객체는 Builder 디자인 패턴으로 빌드할 객체입니다.
- 다음은 Builder 인터페이스 입니다.
public interface IProductStockReportBuilder
{
void BuildHeader();
void BuildBody();
void BuildFooter();
ProductStockReport GetReport();
}
- 이 인터페이스를 구현할 구체적인 빌더 클래스가 ProductStockReport 객체에 대한 모든 부분을 만들고 해당 객체도 반환해야 함을 알 수 있습니다.
- 이제 IProductStockReportBuilder 인터페이스를 상속받는 구현체를 구현해 봅니다.
public class ProductStockReportBuilder : IProductStockReportBuilder
{
private ProductStockReport _productStockReport;
private IEnumerable<Product> _products;
public ProductStockReportBuilder(IEnumerable<Product> products)
{
_products = products;
_productStockReport = new ProductStockReport();
}
public void BuildHeader()
{
_productStockReport.HeaderPart = $"STOCK REPORT FOR ALL THE PRODUCTS ON DATE: {DateTime.Now}\n";
}
public void BuildBody()
{
_productStockReport.BodyPart = string.Join(Environment.NewLine, _products.Select(p => $"Product name: {p.Name}, product price: {p.Price}"));
}
public void BuildFooter()
{
_productStockReport.FooterPart = "\nReport provided by the IT_PRODUCTS company.";
}
public ProductStockReport GetReport()
{
var productStockReport = _productStockReport;
Clear();
return productStockReport;
}
private void Clear() => _productStockReport = new ProductStockReport();
}
- 이 로직은 매우 간단합니다.
- 보고서에 필요한 모든 제품을 수신하고 _productStockReport개체를 인스턴스화합니다.
- 그런 다음 객체의 모든 부분을 만들고 마지막으로 반환합니다.
- GetReprot 메서드에서 객체를 재설정하고 다른 보고서를 만들 준비가 되도록 새 인스턴스를 준비합니다.
- 빌드 로직이 끝나면 클라이언트 클래스에서 객체 빌드를 시작하거나 Director 클래스 내부의 클라이언트 클래스에서 빌드 프로세스를 캡슐화할 수도 있습니다.
public class ProductStockReportDirector
{
private readonly IProductStockReportBuilder _productStockReportBuilder;
public ProductStockReportDirector(IProductStockReportBuilder productStockReportBuilder)
{
_productStockReportBuilder = productStockReportBuilder;
}
public void BuildStockReport()
{
_productStockReportBuilder.BuildHeader();
_productStockReportBuilder.BuildBody();
_productStockReportBuilder.BuildFooter();
}
}
StockReport 객체 생성
class Program
{
static void Main(string[] args)
{
var products = new List<Product>
{
new Product { Name = "Monitor", Price = 200.50 },
new Product { Name = "Mouse", Price = 20.41 },
new Product { Name = "Keyboard", Price = 30.15}
};
var builder = new ProductStockReportBuilder(products);
var director = new ProductStockReportDirector(builder);
director.BuildStockReport();
var report = builder.GetReport();
Console.WriteLine(report);
}
}
Fluent Builder 생성
- Flunet Builder 는 빌더 디자인 패턴의 작은 변형으로 빌더 호출을 다른 작업으로 연결할 수 있습니다.
- Fluent 빌더를 구현하기 위해 먼저 빌더 인터페이스를 변경합니다.
public interface IProductStockReportBuilder
{
IProductStockReportBuilder BuildHeader();
IProductStockReportBuilder BuildBody();
IProductStockReportBuilder BuildFooter();
ProductStockReport GetReport();
}
ProductStockReportBuilder
클래스의 구현도 수정합니다.
public IProductStockReportBuilder BuildHeader()
{
_productStockReport.HeaderPart = $"STOCK REPORT FOR ALL THE PRODUCTS ON DATE: {DateTime.Now}\n";
return this;
}
public IProductStockReportBuilder BuildBody()
{
_productStockReport.BodyPart = string.Join(Environment.NewLine, _products.Select(p => $"Product name: {p.Name}, product price: {p.Price}"));
return this;
}
public IProductStockReportBuilder BuildFooter()
{
_productStockReport.FooterPart = "\nReport provided by the IT_PRODUCTS company.";
return this;
}
public void BuildStockReport()
{
_productStockReportBuilder
.BuildHeader()
.BuildBody()
.BuildFooter();
}
728x90
'C#' 카테고리의 다른 글
[C# 디자인패턴] Factory Method 패턴 (0) | 2022.11.01 |
---|---|
[C# 디자인 패턴] 재귀 제네릭을 사용한 Fluent Builder 패턴 (0) | 2022.10.31 |
[C#] 분산 추적 이란? (0) | 2022.07.29 |
[C#] dotnet Memory 누수 체크 (0) | 2022.07.22 |
[C#] C# Mapster 예제 - Object - Object Merge 매핑하기 (0) | 2022.05.12 |
이 글을 공유하기