For example let's look at making a three part dinner, so to me a three part dinner is composed of a protein, a starch and a salad; i basically eat this for dinner almost everyday, but the components of the dinner vary. one day i might do Salmon, spinach, yams, another day i might do chicken breast, caesar salad and buckwheat. the point is that the dinner itself is the same, but the components of the dinner are different.
To get started we are going to need a Dinner class that store all of the properties of our dinner
enum ProtienStyle {raw = 0, bloody = 10, rare = 30, medium = 60, wellDone = 90 }
enum Protien { Chicken= 1, Turkey=2, Salmon=4, Ostrich=8, Squid=16, Bison=32 }
enum Green { Cabbage = 1, Salad = 2, Spinach = 4, Pickles = 8, Cucumber =
16, Peppers = 32, Carrots = 64 }
enum Starch { Yams, Potatos, Buckweat, Bread }
class Dinner
{
public ProtienStyle ProtienStyle { get; set; }
public Protien Protien { get; set; }
public Green Salad { get; set; }
public Starch Starch { get; set; }
public string
Display()
{
var sb = new
StringBuilder();
string protiens = Enum.GetValues(typeof(Protien)).Cast<Protien>()
.Where(p => (p & Protien) ==
p)
.Select(g => g.ToString())
.Aggregate((x, y) => $"{x}, {y}");
sb.AppendLine($"Protien:{protiens} are {ProtienStyle.ToString()}");
sb.AppendLine($"Starch:{Starch.ToString()}");
string ingredients = Enum.GetValues(typeof(Green)).Cast<Green>()
.Where(i => (i & Salad) ==
i)
.Select(g => g.ToString())
.Aggregate((x, y) => $"{x}, {y}");
sb.AppendLine($"Salad:{ingredients}");
return sb.ToString();
}
}
abstract class DinnerBuilder
{
public Dinner Dinner { get; private set; } = new Dinner();
public abstract void
MakeSalad();
public abstract void
CookStarch();
public abstract void
CookMeat();
}
class SeafoodDinner : DinnerBuilder
{
public SeafoodDinner() => Dinner.ProtienStyle = ProtienStyle.raw;
public override void
CookMeat() => Dinner.Protien = Protien.Salmon |
Protien.Squid;
public override void
CookStarch() => Dinner.Starch = Starch.Yams;
public override void
MakeSalad() => Dinner.Salad = Green.Cabbage;
}
class SurfAndTurfDinner : DinnerBuilder
{
public SurfAndTurfDinner() => Dinner.ProtienStyle =
ProtienStyle.rare;
public override void
CookMeat() => Dinner.Protien = Protien.Bison |
Protien.Squid;
public override void
CookStarch() => Dinner.Starch = Starch.Buckweat;
public override void
MakeSalad() => Dinner.Salad = Green.Salad | Green.Peppers;
}
we can see that this implementations of our Builder class really have no logic, they just hold our data, now our logic is in our DinnerCooker class, this would be referred to as the director.
class DinnerCooker
{
DinnerBuilder _dinnerBuilder;
public DinnerCooker(DinnerBuilder dinnerBuilder)
=> _dinnerBuilder = dinnerBuilder;
public void
CookDinner()
{
_dinnerBuilder.CookStarch();
_dinnerBuilder.CookMeat();
_dinnerBuilder.MakeSalad();
}
public Dinner GetDinner() => _dinnerBuilder.Dinner;
}
in our data cooker, is where the logic sits; the order you'd create your dinner, you'd start with your starch because that takes the longest, then you'd start your meat, and then while those two where cooking you'd make your salad.
now let's take a look at our main
class Program
{
static void Main(string[] args)
{
var dc1 = new DinnerCooker(new SeafoodDinner());
dc1.CookDinner();
Console.WriteLine(dc1.GetDinner().Display());
var dc2 = new
DinnerCooker(new
SurfAndTurfDinner());
dc2.CookDinner();
Console.WriteLine(dc2.GetDinner().Display());
}
}
using System;
using System.Linq;
using System.Text;
namespace pc.patternBuilder
{
enum ProtienStyle { raw = 0, bloody = 10, rare = 30, medium = 60, wellDone = 90 }
enum Protien { Chicken = 1, Turkey = 2, Salmon = 4, Ostrich = 8, Squid = 16,
Bison = 32 }
enum Green { Cabbage = 1, Salad = 2, Spinach = 4, Pickles = 8, Cucumber =
16, Peppers = 32, Carrots = 64 }
enum Starch { Yams, Potatos, Buckweat, Bread }
class Dinner
{
public ProtienStyle ProtienStyle { get; set; }
public Protien Protien { get; set; }
public Green Salad { get; set; }
public Starch Starch { get; set; }
public string
Display()
{
var sb = new
StringBuilder();
string protiens = Enum.GetValues(typeof(Protien)).Cast<Protien>()
.Where(p => (p &
Protien) == p)
.Select(g => g.ToString())
.Aggregate((x, y) => $"{x}, {y}");
sb.AppendLine($"Protien:{protiens} are {ProtienStyle.ToString()}");
sb.AppendLine($"Starch:{Starch.ToString()}");
string ingredients = Enum.GetValues(typeof(Green)).Cast<Green>()
.Where(i => (i & Salad)
== i)
.Select(g => g.ToString())
.Aggregate((x, y) => $"{x}, {y}");
sb.AppendLine($"Salad:{ingredients}");
return sb.ToString();
}
}
abstract class DinnerBuilder
{
public Dinner Dinner { get; private set; } = new Dinner();
public abstract void
MakeSalad();
public abstract void
CookStarch();
public abstract void
CookMeet();
}
class SeafoodDinner : DinnerBuilder
{
public SeafoodDinner() => Dinner.ProtienStyle = ProtienStyle.raw;
public override void
CookMeet()
=> Dinner.Protien =
Protien.Salmon | Protien.Squid;
public override void
CookStarch()
=> Dinner.Starch = Starch.Yams;
public override void
MakeSalad()
=> Dinner.Salad = Green.Cabbage;
}
class SurfAndTurfDinner : DinnerBuilder
{
public SurfAndTurfDinner() => Dinner.ProtienStyle =
ProtienStyle.rare;
public override void
CookMeet()
=> Dinner.Protien =
Protien.Bison | Protien.Squid;
public override void
CookStarch()
=> Dinner.Starch =
Starch.Buckweat;
public override void
MakeSalad()
=> Dinner.Salad = Green.Salad |
Green.Cucumber | Green.Peppers;
}
class DinnerCooker
{
DinnerBuilder _dinnerBuilder;
public DinnerCooker(DinnerBuilder dinnerBuilder)
=> _dinnerBuilder =
dinnerBuilder;
public void
CookDinner()
{
_dinnerBuilder.CookMeet();
_dinnerBuilder.CookStarch();
_dinnerBuilder.MakeSalad();
}
public Dinner GetDinner() => _dinnerBuilder.Dinner;
}
class Program
{
static void Main(string[] args)
{
var dc1 = new
DinnerCooker(new
SeafoodDinner());
dc1.CookDinner();
Console.WriteLine(dc1.GetDinner().Display());
var dc2 = new
DinnerCooker(new
SurfAndTurfDinner());
dc2.CookDinner();
Console.WriteLine(dc2.GetDinner().Display());
}
}
}