Design patterns – Builder

Builder pattern should be used when you try to create similar complex objects. These objects are created step by step. You want to separate creation logic from objects representation.

Participants are:
Product – objects which are being created (Bungalow and BlockOfFlats in our example).
Builders – objects which create products step by step (BungalowBuilder, BlockOfFlatsBuilder). They are based on HouseBuilder class.
HouseDirector – object which uses different builders (implementing the same interface) to get different products.

Our products with base class:

    /// <summary>
    /// Base class for created (by builders) houses.
    /// </summary>
    class HouseBase
    {
        public HouseBase() { }

        public string Basement { get; set; }
        public string MainPart { get; set; }
        public string Roof { get; set; }

        /// <summary>
        /// Describes created house.
        /// </summary>
        /// <returns></returns>
        public string DescribeYourself()
        {
            var sb = new StringBuilder();
            sb.Append("I have: ");
            sb.Append(Environment.NewLine);
            sb.Append(Basement);
            sb.Append(Environment.NewLine);
            sb.Append(MainPart);
            sb.Append(Environment.NewLine);
            sb.Append(Roof);
            return sb.ToString();
        }
    }
	
    /// <summary>
    /// Represents block of flats (type of a house).
    /// </summary>
    class BlockOfFlats : HouseBase
    {
        public int NumberOfFloors
        {
            get { return 15; }
        }

        public int NumberOfFlats
        {
            get { return NumberOfFlats * 10; }
        }
    }
	
    /// <summary>
    /// Represents bungalow (type of a house).
    /// </summary>
    class Bungalow : HouseBase
    {
        public void LightTheFireplace()
        {
            throw new NotImplementedException();
        }
    }

Our concrete builders with base class:

    /// <summary>
    /// Abstract class as a base for concrete house builders.
    /// Contains abstract methods which should be implemented separately in each type of concrete builder.
    /// </summary>
    abstract class HouseBuilder
    {
        protected HouseBase _house;

        public abstract void CreateBasement();
        public abstract void CreateWalls();
        public abstract void CreateRoof();

        public HouseBase GetHouse()
        {
            return _house;
        }
    }
	
    /// <summary>
    /// Represents a builder which can create a block of flats.
    /// </summary>
    class BlockOfFlatsBuilder : HouseBuilder
    {
        public BlockOfFlatsBuilder()
        {
            _house = new BlockOfFlats();
        }

        public override void CreateBasement()
        {
            _house.Basement = "deep basement with many rooms";
        }

        public override void CreateRoof()
        {
            _house.Roof = "flat roof high above the ground";
        }

        public override void CreateWalls()
        {
            _house.MainPart = "15 floors";
        }
    }
	
    /// <summary>
    /// Represents a builder which can create a bungalow.
    /// </summary>
    class BungalowBuilder : HouseBuilder
    {
        public BungalowBuilder()
        {
            _house = new Bungalow();
        }

        public override void CreateBasement()
        {
            _house.Basement = "no basement";
        }

        public override void CreateRoof()
        {
            _house.Roof = "ridge roof with small chimney";
        }

        public override void CreateWalls()
        {
            _house.MainPart = "single floor";
        }
    }

Our director:

    /// <summary>
    /// Director uses builder to construct a house.
    /// </summary>
    class HouseDirector
    {
        /// <summary>
        /// Constructs appropriate house step by step basing on logic in builder.
        /// </summary>
        /// <param name="builder"></param>
        /// <returns></returns>
        public HouseBase Construct(HouseBuilder builder)
        {
            builder.CreateBasement();
            builder.CreateWalls();
            builder.CreateRoof();
            return builder.GetHouse();
        }
    }

The sample usage:

        private static void BuilderUsage()
        {
            var houseDirector = new HouseDirector();

            var bungalowBuilder = new BungalowBuilder();
            var house1 = houseDirector.Construct(bungalowBuilder);
            Console.WriteLine(house1.DescribeYourself());

            var blockOfFlatsBuilder = new BlockOfFlatsBuilder();
            var house2 = houseDirector.Construct(blockOfFlatsBuilder);
            Console.WriteLine(house2.DescribeYourself());

        }
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s