Tuesday, February 07, 2012

Example of Builder Design Pattern

I happened to come across an interesting idea from a Java blogger regards the Builder design pattern. For those of you who are not familiar with this pattern, check out the Wikipedia explanation. Check out this code:

    public class Address
    {
        public string Protocol { get; set; }
        public string Description { get; set; }
        public int Port { get; set; }
        public string Path { get; set; }
        public string Url { get; set; }

        private Address(AddressBuilder addressBuilder)
        {
            this.Protocol = addressBuilder._protocol;
            this.Url = addressBuilder._url;
            this.Port = addressBuilder._port;
            this.Path = addressBuilder._path;
            this.Description = addressBuilder._description;
        }

        public interface IBuild
        {
            Address Build();
            IBuild Description(string description);
            IBuild Path(string path);
            IBuild Protocol(string protocol);
        }

        public interface IPort
        {
            IBuild Port(int port);
        }

        public interface IUrl
        {
            IPort Url(string url);
        }

        public static IUrl Builder()
        {
            return new AddressBuilder();
        }

        public class AddressBuilder : IUrl, IBuild, IPort
        {
            public string _description;
            public string _path;
            public int _port;
            public string _protocol;
            public string _url;

            public Address Build()
            {
                return new Address(this);
            }

            public IBuild Description(string description)
            {
                this._description = description;
                return this;
            }

            public IBuild Path(string path)
            {
                this._path = path;
                return this;
            }

            public IBuild Port(int port)
            {
                this._port = port;
                return this;
            }

            public IBuild Protocol(string protocol)
            {
                this._protocol = protocol;
                return this;
            }

            public IPort Url(string url)
            {
                this._url = url;
                return this;
            }
        }
    }

Now there’s a lot going on here, but lets see what the above code allows us to do:

var address = Address.Builder()
    .Url("ddd")
    .Port(23)
    .Build();

We can build an Address instance using the Builder pattern, which has this nice fluent API to it. The key idea is that, since port and url are mandatory fields, we have designed the builder in such a way that those fields must be given a value before the “Build()” method can be called. If you look at the code you’ll see that this is achieved by having a nested “Builder” class that implements private interfaces associated with the Address object. The method “Address.Builder()” returns a new Builder instance via the IUrl interface. That interface has a “Port” method which must be called. The Port method returns an IBuild interface which has the “Build()” method which will actually create the Address instance.

Have a play around with this code, I think it’s a very nice way to create objects whilst making it clear which properties are mandatory.