Categories: Design Pattern

Creational Patterns – Builder

Builder This pattern allows making different types and representations of the object using the same construction code.

From Design Pattern – Creational Patterns

Structure

Builder pattern class diagram UML

Applicability

  • Construct the object trees or other complex objects.
  • Analysis of the complex objects and create different representations of some objects.

Pros and Cons

PROS

  • It is making objects step-by-step that limit steps or running steps order.
  • It can reuse the same structure code when building an instance.
  • Single Responsibility Principle.

Cons

  • The same structure source code will become complex because it requests creating multiple new classes or new interface classes.

How to Implement

#1 Basic Sample

public interface IBuilder<T> where T :class
{
 void BuildItem();
}

public class BuilderRepo<T> : IBuilder<T> where T : class
{
 private SubRepositroy<T> _product = new SubRepositroy<T>();

 public BuilderRepo()
 {
  this.Reset();
 }

 public void Reset()
 {
  this._product = new SubRepositroy<T>();
 }

 public void BuildItem()
 {
  this._product.Add("PartA1");
 }

 public SubRepositroy<T> GetProduct()
 {
  SubRepositroy<T> result = this._product;

  this.Reset();

  return result;
 }
}

public class SubRepositroy<T> where T : class
{
 private readonly List<T> _parts = new List<T>();

 public void Add(string part)
 {
  this._parts.Add(part as T);
 }

 public string ListParts()
 {
  string str = string.Empty;

  for (int i = 0; i < this._parts.Count; i++)
  {
   str += this._parts[i] + ", ";
  }

  str = str.Remove(str.Length - 2); // removing last ",c"

  return "Product parts: " + str + "\n";
 }
}


public class Director<T> where  T : class
{
 private IBuilder<T> _builder;

 public IBuilder<T> Builder
 {
  set { _builder = value; }
 }

 public void BuildMinimalViableProduct()
 {
  this._builder.BuildItem();
 }

 public void BuildFullFeaturedProduct()
 {
  this._builder.BuildItem();
 }
}

#2 Web Application Project

Step 1 Create a new interface class file under the Core project and a new repository class file under the Infra project. A new interface class file name sets “IBuilder.” Another file’s name sets “BuilderRepo.”

Fig 1 Builder solution explorer

Step 2 Add a few functions in the IBuilder, then the BuilderRepo file inherits the IBuilder.

Fig 2 IBuilder interface class file source code
public interface IBuilder<T> where T : class
{
 Task<IEnumerable<T>> GetAll();
 Task<T> GetById(int id);
 Task<IEnumerable<T>> Complate(List<T> t1, List<T> t2);
}

Step 3 Statement the IGenericTypeRepository by the dependency injection method in the BuilderRepo file.

Fig 3 BulderRepo repository class file source code
public class BuilderRepo<T> : IBuilder<T> where T : class
{
 private readonly IGenericTypeRepository<T> repo;

 public BuilderRepo(IGenericTypeRepository<T> _repo)
 {
  this.repo = _repo;
 }

 public Task<IEnumerable<T>> GetAll()
 {
  return Task.Run(() => repo.GetAll() as IEnumerable<T>);
 }

 public Task<T> GetById(int id)
 {
  return Task.Run(async () => await repo.GetById(id) as T);
 }

 public Task<IEnumerable<T>> Complate(List<T> source, List<T> target)
 {
  return Task.Run(() => source.Concat(target) as IEnumerable<T>);
 }
}

Step 4 Create the new class file, the new controller file, and the view file under the web project. The new class file name sets “Director” under the Core project. The new controller file name sets “BuilderController.” The view file name sets “Index” under the web project’s views folder.

Fig 4 Direct class file and BuilderController file – solution explorer

Step 5 Statement the IBuilder by dependency injection methods, and create a few methods in the Director file under the Core project.

public class Director<T> : IDisposable where T : class
{
 private readonly IBuilder<T> builder;

 public Director(IBuilder<T> _builder)
 {
  this.builder = _builder;
 }

 public IEnumerable<T> DefaultResult()
 {
  return builder.GetAll().Result;
 }

 public IEnumerable<T> Combine()
 {
  List<T> sourceList = new List<T> { builder.GetById(1).Result as T };
  List<T> targetList = new List<T> { builder.GetById(2).Result as T };
  return builder.Complate(sourceList, targetList).Result;
 }

 public IEnumerable<T> AntiCombine()
 {
  List<T> sourceList = new List<T> { builder.GetById(2).Result as T };
  List<T> targetList = new List<T> { builder.GetById(1).Result as T };
  return builder.Complate(sourceList, targetList).Result;
 }

 public void Dispose()
 {
  GC.SuppressFinalize(this);
 }
}

Step 6 Statement Director class in the BuilderController file.

public class BuilderController : Controller
{
 private readonly Director<Enterprise_MVC_Core> director;

 public BuilderController(IBuilder<Enterprise_MVC_Core> repo)
 {
  this.director = new Director<Enterprise_MVC_Core>(repo);
 }

 public IActionResult Index()
 {
  Tuple<IEnumerable<Enterprise_MVC_Core>, IEnumerable<Enterprise_MVC_Core>> repoView;

  var Result = director.Combine();
  var AntiResult = director.AntiCombine();

  repoView = new Tuple<IEnumerable<Enterprise_MVC_Core>, IEnumerable<Enterprise_MVC_Core>>(Result, AntiResult);

  return View(repoView);
 }
}

Reference

davidsky69

View Comments

Recent Posts

API Gateway in .NET 5 with Ocelot

What is the API gateway? An API gateway is an API management tool that sits…

3 years ago

.NET 5 application with Onion architecture

The .NET 5 SDK is a kind of milestone in the .NET world. The .NET…

4 years ago

SOLID Principles – Dependency inversion principle

In object-oriented design, the dependency inversion principle is a specific methodology for loosely coupling software…

4 years ago

SOLID Principles – Interface segregation principle

In the field of software engineering, the interface segregation principle (ISP) states that no code…

4 years ago

SOLID Principles – Liskov substitution principle

Subtype Requirement: Let  be a property provable about objects  of type T. Then  should be true for objects  of type S where S is…

4 years ago

SOLID Principles – Open-closed principle

In object-oriented programming, the open–closed principle states "software entities (classes, modules, functions, etc.) should be…

4 years ago