Builder Design Pattern Implementation

Suggested Videos
Part 9 - Factory Method Design Pattern - Text - Slides
Part 10 - Abstract Factory Design Pattern - Text - Slides
Part 11 - Builder Desing Pattern Implementation - Text - Slides

In this video we will learn Implementing Builder design pattern

(追記) (追記ここまで)
Business Requirement : Provide an option to choose and build configuration of the system which is allocated to the employees. The configuration options that user can choose are RAM, HDD, USB Mouse etc. Choose the system configurations based on the computer type that we need to build. For example, A laptop users can choose touch screen and the desktop users can configure keyboard and mouse.

(追記) (追記ここまで)
Here are the steps to implement builder design pattern

Step 1 : Add ISystemBuilder interface

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Web.Builder.IBuilder
{
publicinterfaceISystemBuilder
{
void AddMemory(string memory);
void AddDrive(string size);

void AddKeyBoard(string type);
void AddMouse(string type);

void AddTouchScreen(string enabled);
ComputerSystem GetSystem();
}
}

Step 2 : Add desktop builder and inherit ISystemBuilder interface and implement the Interface methods and assign the properties to the computer system that is being built.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Web.Builder.IBuilder;

namespace Web.Builder.ConcreteBuilder
{
publicclassDesktopBuilder : ISystemBuilder
{
ComputerSystem desktop = newComputerSystem();
publicvoid AddDrive(string size)
{
desktop.HDDSize = size;
}
publicvoid AddKeyBoard(string type)
{
desktop.KeyBoard = type;
}
publicvoid AddMemory(string memory)
{
desktop.RAM = memory;
}
publicvoid AddMouse(string type)
{
desktop.Mouse = type;
}
publicvoid AddTouchScreen(string enabled)
{
return;
}
publicComputerSystem GetSystem()
{
return desktop;
}
}
}

Step 3 : Add laptop builder and inherit ISystemBuilder interface and implement the Interface methods and assign the properties to the computer system that is being built.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Web.Builder.IBuilder;

namespace Web.Builder.ConcreteBuilder
{
publicclassLaptopBuilder : ISystemBuilder
{
ComputerSystem laptop = newComputerSystem();
publicvoid AddDrive(string size)
{
laptop.HDDSize = size;
}

publicvoid AddKeyBoard(string type)
{
return;
}

publicvoid AddMemory(string memory)
{
laptop.RAM = memory;
}

publicvoid AddMouse(string type)
{
return;
}

publicvoid AddTouchScreen(string enabled)
{
laptop.TouchScreen = enabled;
}

publicComputerSystem GetSystem()
{
return laptop;
}
}
}

Step 4 : Add configuration builder class which is the director to build the system

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Web;
using Web.Builder.IBuilder;

namespace Web.Builder.Director
{
publicclassConfigurationBuilder
{
publicvoid BuildSystem(ISystemBuilder systembuilder
, NameValueCollection collection)
{
systembuilder.AddDrive(collection["Drive"]);
systembuilder.AddMemory(collection["RAM"]);
systembuilder.AddMouse(collection["Mouse"]);
systembuilder.AddKeyBoard(collection["Keyboard"]);
systembuilder.AddTouchScreen(collection["TouchScreen"]);
}
}
}

Step 5 : Remove the constructor with the parameters and change the private properties to public so that they can be initialized from the concrete builder classes

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

namespace Web
{
publicclassComputerSystem
{
publicstring RAM { get; set; }
publicstring HDDSize { get; set; }
publicstring KeyBoard { get; set; }
publicstring Mouse { get; set; }
publicstring TouchScreen { get; set; }
public ComputerSystem()
{
}
}
}

Step 6 : Enhance the BuildSystem action method from the previous session by returning desktop and laptop views based on the system allocated to the employees

[HttpGet]
publicActionResult BuildSystem(int? employeeID)
{
Employee employee = db.Employees.Find(employeeID);
if (employee.ComputerDetails.Contains("Laptop"))
return View("BuildLaptop", employeeID);
else
return View("BuildDesktop", employeeID);
}

Step 7 : Add Build laptop action method as shown below

[HttpPost]
publicActionResult BuildLaptop(FormCollection formCollection)
{
Employee employee =
db.Employees.Find(Convert.ToInt32(formCollection["employeeID"]));
//Concrete Builder
ISystemBuilder systemBuilder = newLaptopBuilder();
//Director
ConfigurationBuilder builder = newConfigurationBuilder();
builder.BuildSystem(systemBuilder, formCollection);
ComputerSystem system= systemBuilder.GetSystem();

employee.SystemConfigurationDetails =
string.Format("RAM : {0}, HDDSize : {1}, TouchScreen: {2}"
, system.RAM, system.HDDSize, system.TouchScreen);

db.Entry(employee).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}

Step 8 : Add build desktop action method as shown below

[HttpPost]
publicActionResult BuildDesktop(FormCollection formCollection)
{
//Step 1
Employee employee
= db.Employees.Find(Convert.ToInt32(formCollection["employeeID"]));
//Step 2 Concrete Builder
ISystemBuilder systemBuilder = newDesktopBuilder();
//Step 3 Director
ConfigurationBuilder builder = newConfigurationBuilder();
builder.BuildSystem(systemBuilder, formCollection);
//Step 4 return the system
ComputerSystem system = systemBuilder.GetSystem();
employee.SystemConfigurationDetails =
string.Format("RAM : {0}, HDDSize : {1}, Keyboard: {2}, Mouse : {3}"
, system.RAM, system.HDDSize, system.KeyBoard, system.Mouse);
db.Entry(employee).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");}

Step 9 : Create Desktop and Laptop views as shown below. On submit post the details to the respective action methods built in step 7 and step 8

@model Int32
@{
ViewBag.Title = "BuildSystem";
}
<h2>Build System</h2>
<style>
input[type=radio] {
border: 0px;
width: 100%;
height: 1em;
}
</style>
@using (Html.BeginForm("BuildDesktop", "Employees", FormMethod.Post ))
{
@Html.AntiForgeryToken()

<divclass="form-horizontal">
<h4>System Configuration</h4>
<hr/>
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.Hidden("employeeID", this.Model.ToString());

<divclass="form-group">
@Html.Label("Memory", htmlAttributes: new { @class = "control-label col-md-2" })
<divclass="col-md-10">
@Html.DropDownList("RAM",
newList<SelectListItem>() {
newSelectListItem (){ Text = "Select", Value="Select"},
newSelectListItem (){ Text = "8GB", Value="8GB"},
newSelectListItem (){ Text = "16GB", Value="16GB"},
newSelectListItem (){ Text = "32GB", Value="32GB"},
}, htmlAttributes: new { @class = "form-control" })

</div>
</div>
<divclass="form-group">
@Html.Label("Drive", htmlAttributes: new { @class = "control-label col-md-2" })
<divclass="col-md-10">
@Html.DropDownList("Drive",
newList<SelectListItem>() {
newSelectListItem (){ Text = "Select", Value="Select"},
newSelectListItem (){ Text = "500GB", Value="500GB"},
newSelectListItem (){ Text = "1TB", Value="1TB"},
}, htmlAttributes: new { @class = "form-control" })

</div>
</div>
<divclass="form-group">
@Html.Label("Mouse", htmlAttributes: new { @class = "control-label col-md-2" })
<divclass="col-md-10">
@Html.DropDownList("Mouse",
newList<SelectListItem>() {
newSelectListItem (){ Text = "Select", Value="Select"},
newSelectListItem (){ Text = "WireLess", Value="USB-WireLess"},
newSelectListItem (){ Text = "Regular-USB", Value="USB"},
}, htmlAttributes: new { @class = "form-control" })

</div>
</div>
<divclass="form-group">
@Html.Label("KeyBoard", htmlAttributes: new { @class = "control-label col-md-2" })
<divclass="col-md-10">
@Html.DropDownList("KeyBoard",
newList<SelectListItem>() {
newSelectListItem (){ Text = "Select", Value="Select"},
newSelectListItem (){ Text = "Wireless", Value="Wireless"},
newSelectListItem (){ Text = "Regular-USB", Value="Regular-USB"},
}, htmlAttributes: new { @class = "form-control" })

</div>
</div>
<divclass="form-group">
<divclass="col-md-offset-2 col-md-10">
<inputtype="submit"value="Create"class="btn btn-default"/>
</div>
</div>
</div>
}

<div>
@Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

@model Int32
@{
ViewBag.Title = "BuildSystem";
}
<h2>Build System</h2>
<style>
input[type=radio] {
border: 0px;
width: 100%;
height: 1em;
}
</style>
@using (Html.BeginForm("BuildLaptop", "Employees", FormMethod.Post))
{
@Html.AntiForgeryToken()

<divclass="form-horizontal">
<h4>System Configuration</h4>
<hr/>
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.Hidden("employeeID", this.Model.ToString());

<divclass="form-group">
@Html.Label("Memory", htmlAttributes: new { @class = "control-label col-md-2" })
<divclass="col-md-10">
@Html.DropDownList("RAM",
newList<SelectListItem>() {
newSelectListItem (){ Text = "Select", Value="Select"},
newSelectListItem (){ Text = "8GB", Value="8GB"},
newSelectListItem (){ Text = "16GB", Value="16GB"},
newSelectListItem (){ Text = "32GB", Value="32GB"},
}, htmlAttributes: new { @class = "form-control" })

</div>
</div>
<divclass="form-group">
@Html.Label("Drive", htmlAttributes: new { @class = "control-label col-md-2" })
<divclass="col-md-10">
@Html.DropDownList("Drive",
newList<SelectListItem>() {
newSelectListItem (){ Text = "Select", Value="Select"},
newSelectListItem (){ Text = "500GB", Value="500GB"},
newSelectListItem (){ Text = "1TB", Value="1TB"},
}, htmlAttributes: new { @class = "form-control" })

</div>
</div>
<divclass="form-group">
@Html.Label("Touch Enbled", htmlAttributes: new { @class = "control-label col-md-2" })
<divclass="col-md-10">
<divclass="col-md-1">
<label>@Html.RadioButton("TouchScreen", "Yes", false, htmlAttributes: new { @class = "radio-inline" }) YES</label>


</div>
<divclass="col-md-1">
<label>@Html.RadioButton("TouchScreen", "NO", false, htmlAttributes: new { @class = "radio-inline" }) NO</label>
</div>
</div>
</div>
<divclass="form-group">
<divclass="col-md-offset-2 col-md-10">
<inputtype="submit"value="Create"class="btn btn-default"/>
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

Step 10 : Run the application and build the system. Notice that depending on the system type the respective system configurations are built.

Step 11 : With this we have successfully addressed requirement by using the builder design pattern

builder design pattern implementation c#

I hope now you got familiar with the builder design pattern.
In the next video, we will discuss how to implement fluent builder pattern and we will also discuss the differences between factory and the builder design pattern.

Design Patterns tutorial for beginners

1 comment:

  1. Looks like this problem needs to be resolved by Factory Method Pattern instead of using Builder Pattern to avoid duplicate code in the concrete builder classes.

    Reply Delete

It would be great if you can help share these free resources

[フレーム]

Subscribe to: Post Comments (Atom)

AltStyle によって変換されたページ (->オリジナル) /