vendredi 22 mai 2015

When to use the builder pattern in real projects? [on hold]

I'd like to know, how you use the builder pattern in your projects...

  • Is it something you often use?
  • What are typical situations when you'd use it?
  • How can I add a syntax to a builder so that I can only call .WithXYZ on a certain object? (see the bottom of the page for more detail)

I tend to use the Builder Pattern for Test Data Builders like for example:

Employee:

public class Employee
{
    public Employee(int id, string firstName, string name, DateTime birthDate, string street, string houseNumber, Color eyeColor)
    {
        this.Id = id;
        this.FirstName = firstName;
        this.Name = name;
        this.BirthDate = birthDate;
        this.Street = street;
        this.HouseNumber = houseNumber;
        this.EyeColor = eyeColor;
    }

    public int Id { get; private set; }

    public string FirstName { get; private set; }

    public string Name { get; private set; }

    public DateTime BirthDate { get; private set; }

    public string Street { get; private set; }

    public string HouseNumber { get; private set; }

    public Color EyeColor { get; private set; }

    public string GetFullName()
    {
        return string.Format("{0} {1}", this.FirstName, this.Name);
    }

    public int GetAge()
    {
        var today = DateTime.Today;
        var alter = today.Year - this.BirthDate.Year;

        if (this.BirthDate > today.AddYears(-alter))
        {
            alter--;
        }

        return alter;
    }

    public string GetAdress()
    {
        return string.Format("{0} {1}", this.Street, this.HouseNumber);
    }
}

Builder:

public class EmployeeBuilder
{
    private int id = 1;

    private string firstname = "aFirstname";

    private string name = "aName";

    private DateTime birthDate = DateTime.Today;

    private string street = "aStreet";

    private string housenumber = "aHousenumber";

    private Color eyeColor = Color.Blue;

    public Employee Build()
    {
        return new Employee(this.id, this.firstname, this.name, this.birthDate, this.street, this.housenumber, this.eyeColor);
    }

    public EmployeeBuilder WithFirstName(string firstname)
    {
        this.firstname = firstname;
        return this;
    }

    public EmployeeBuilder WithName(string name)
    {
        this.name = name;
        return this;
    }

    public EmployeeBuilder WithBirthDate(DateTime birthDate)
    {
        this.birthDate = birthDate;
        return this;
    }

    public EmployeeBuilder WithStreet(string street)
    {
        this.street = street;
        return this;
    }

    public EmployeeBuilder WithHouseNumber(string housenumber)
    {
        this.housenumber = housenumber;
        return this;
    }

    public EmployeeBuilder WithEyeColor(Color eyeColor)
    {
        this.eyeColor = eyeColor;
        return this;
    }

    public static implicit operator Employee(EmployeeBuilder instance)
    {
        return instance.Build();
    }
}

Unit Test:

[Test]
public void GetFullName_WhenNameAndFirstnameAreGiven_ThenFullNameIsReturned()
{
    Employee testee = new EmployeeBuilder()
                            .WithFirstName("Anon")
                            .WithName("Ymous");

    var result = testee.GetFullName();

    result.Should().Be("Anon Ymous");
}

And is it possible to implement a "syntax" for the builder like for example if we had a car builder (car consists of body, doors, windows, wheels) that we can only call .WithWindows(...) on a door object?

Thanks in advance

Aucun commentaire:

Enregistrer un commentaire