Design Patterns

Last Updated: 9/8/2024

Builder Pattern

  • Separate the construction of an object from its representation

Classical Structure

Builder Classical Structure

Scenario

  • Export power point slide to PDF, Movie etc

Problem

public class Slide
{
    public string Text { get; init; }
    public Slide(string text)
    {
        Text = text;
    }
}
public class PdfDocument
{
    public void AddPage(string text)
    {
        Console.WriteLine("Adding a page to pdf");
    }
}
public class Movie
{
    public void AddFrame(string text, int duration)
    {
        Console.WriteLine("Adding a frame to movie");
    }
}
public enum PresentationFormat
{
    PDF,
    Movie
}
public class Presentation
{
    List<Slide> slides = new List<Slide>();

    public void AddSlide(Slide slide)
    {
        slides.Add(slide);
    }

    public void Export(PresentationFormat presentationFormat)
    {
        if (presentationFormat == PresentationFormat.PDF)
        {
            PdfDocument pdfDocument = new PdfDocument();
            foreach (Slide slide in slides)
            {
                pdfDocument.AddPage(slide.Text);
            }
        }
        else if (presentationFormat == PresentationFormat.Movie) 
        { 
            Movie movie = new Movie();
            foreach (Slide slide in slides)
            {
                movie.AddFrame(slide.Text, 10);
            }
        }
    }
}
  • Violates Open Closed Principle
  • Tightly Coupled
  • Presentation is aware of the inner details of other classes
  • Duplicate logic

Solution

public interface IPresentationBuilder
{
    void AddSlide(Slide slide);
}
public class MovieBuilder : IPresentationBuilder
{
    Movie movie = new Movie();

    public void AddSlide(Slide slide)
    {
        movie.AddFrame(slide.Text, 10);
    }

    public Movie getMovie() { return movie; }
}
public class PdfDocumentBuilder : IPresentationBuilder
{
    PdfDocument pdfDocument = new PdfDocument();

    public void AddSlide(Slide slide)
    {
        pdfDocument.AddPage(slide.Text);
    }

    public PdfDocument GetPdfDocument() => pdfDocument;
}
public class Presentation
{
    List<Slide> slides = new List<Slide>();

    public void AddSlide(Slide slide)
    {
        slides.Add(slide);
    }

    public void Export(IPresentationBuilder builder)
    {
        foreach (var slide in slides)
        {
            builder.AddSlide(slide);
        }
    }
}

Example Structure

Builder Example Structure

Example Code