I recently attended a Leeds Sharp user group meeting on design patterns. Grant Crofton was presenting an example of using the builder pattern in tests and showed a neat trick that can be used in C# when using builders.
A builder class has a selection of “with” methods corresponding to different properties of the target object, where these are called in a chain. The final method call in this chain is then usually a Build() method that converts the builder object into the desired target object, i.e.
Order order = OrderBuilder.anOrder().withCustomer(customer).withAddress(address).withPostage(2.00).build();
I learned that by using implicit type conversion in C# with the “implicit operator” keywords, this final Build() call can be omitted. For example, here I have two NUnit test methods, the first of which uses a final Build() call for the builder object and the second which uses implicit type conversion:
[TestFixture] class AddressTest { [Test] public void AddressWithHouseNameAndNoNumberDisplaysCorrectly() { Address address = AddressBuilder.anAddress() .WithHouseName("Dunroamin") .WithStreet("Golden Meadow Lane") .WithTown("Otley St Catchpole") .Build(); Assert.That(address.ToString(), Is.EqualTo("Dunroamin, Golden Meadow Lane, Otley St Catchpole")); } [Test] public void AddressWithNumberAndBuildingNameDisplaysCorrectly() { Address address = AddressBuilder.anAddress() .WithNumber("5") .WithBuildingName("Hipster Flats") .WithStreet("Ironic Street") .WithTown("Hipsterville"); Assert.That(address.ToString(), Is.EqualTo("5 Hipster Flats, Ironic Street, Hipsterville")); } }
The code to achieve this implicit type conversion in the AddressBuilder class is:
public static implicit operator Address(AddressBuilder builder) { return new Address(builder.HouseName, builder.Number, builder.BuildingName, builder.Street, builder.Town); }
The full code for this builder example is available on GitHub
