Sunday, 29 October 2017

Builder Pattern

The builder pattern is used to separate logic from data, it's defined as "Separation of the construction of a complex object from its representation so that the same construction process can be used to create multiple representations." What we are aiming for is to reuse common logic to create objects of the same type but different representations.

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();
    }

}

above we define our dinner class, which stores the various components of our dinner next we need to define an abstract dinner builder.

abstract class DinnerBuilder
{
    public Dinner Dinner { get; private set; } = new Dinner();
    public abstract void MakeSalad();
    public abstract void CookStarch();
    public abstract void CookMeat();

}


this class defines the abstraction that our concrete implementations are going to have to define, next let's look at our implementations

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());
    }

}

and as you can see we create our dinnerCooker and pass in our builder to it; the cooker then uses the data in the builder to create our dinner.

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());
        }
    }
}


Friday, 27 October 2017

Bridge Pattern

The bridge pattern is described as "Decoupling an abstraction from it's implementation so that the two can vary independently." When we think of what an abstraction is, we can think of an interface and the implementation would be the coupling of that interface and the class that implements it;

using System;
using System.Linq;

namespace pc.patternBridge
{
    interface IPerson
    {
        string Name { get; set; }
        void Display();
    }

    class Person : IPerson
    {
        public string Name { get; set; }
        public Person(string name) => Name = name;
        public virtual void Display() => Console.WriteLine($"\n{Name}");
    }

    class StudentPerson 
    {
        static int _runningID = 0;
        public int Id { get; set; } = _runningID++;
        public string[] Classes { get; private set; } = new string[6];
        public Student(string name, params string[] classes) : base(name) 
            => Classes = classes;
       
       public override void Display()
        {
            base.Display();
            Console.WriteLine("StudentId: " + Id);
            Console.WriteLine("Classes: " + Classes.Aggregate((x, y) => $"{x}, {y}"));  
        }
    }

    class EmployeePerson 
    {
        static int _runningID = 0;
        public int Id { get; set; } = _runningID++;
        public string JobTitle { get; set; }
        public Employee(string name, string jobTitle) : base(name) 
            => JobTitle = jobTitle;

        public override void Display()
        {
            base.Display();
            Console.WriteLine("Job Title:" + JobTitle);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var people = new Person[] {
                new Person("Pawel Chooch"),new Person("Marin Smartzki"),
                new Student("Magda Tievonik", "Physics", "Math", "Chemestry" ),
                new Student("Jakub Tievonik", "Art", "English Lit", "Poetry" ),
                new Employee("Cezar Zenon", "Software Engineer")
            };

            foreach (var p in people)
                p.Display();
        }
    }
}


now if we look at the above code we see that our display method is defined in our IPerson interface and tightly coupled to our person class, we then override it in our subclasses. now in this instance it's fine, but if for some reason we wanted our code to have some sort of logic that could decide how to print out our various models, or perhaps we wanted the ability to provide each model in our hierarchy a different implementation of our Display function we'd have to separate our display abstraction from our person class, so what we can do is to create an abstract display class.

interface IPerson
{
    string Name { get; set; }
    void Display();
}

abstract class Display
{
    public abstract string Print(object human);
}

class Person : IPerson
{
    Display _display;
    public string Name { get; set; }
    public Display(Display display) => _display = display;
    public Display(Display display, string name)
        : this(display) => Name = name;
    public void Display() => Console.WriteLine(_display?.Print(this));
}

now what we did here is we created an abstract Display class that has one function that returns a string, that is the Print function that takes in an object called human. Then in our Person implementation of the Display method from the IPerson interface, we output the result of our print function from our Display abstraction. 

now since we are now passing in our display behavior to our base person class, we no longer have to override it in our subclasses.

class StudentPerson 
{
    static int _runningID = 0;
    public int Id { get; set; } = _runningID++;
    public string[] Classes { get; private set; } = new string[6];
    public Student(Display display, string name, params string[] classes)
        : base(display, name) => Classes = classes;
}

class EmployeePerson 
{
    static int _runningID = 0;
    public int Id { get; set; } = _runningID++;
    public string JobTitle { get; set; }
    public Employee(Display display, string name, string jobTitle)
        : base(display, name) => JobTitle = jobTitle;
}

So now you can see that our subclasses no longer override the Display method, but instead what we are now going to need is implementations of our Display abstraction.

class PersonDisplay : Display
{
    public override string Print(object human)
    {
        var _person = human as Person;
        return $"Person: {_person.Name}";
    }
}

class StudentDisplay : Display
{
    public override string Print(object human)
    {
        var _student = human as Student;
        var classes = _student.Classes.Aggregate((x, y) => $"{x}, {y}");
        return $"Student #:{_student.Id}; {_student.Name} is taking {classes}";
    }
}

class EmployeeDisplay : Display
{
    public override string Print(object human)
    {
        var _employee = human as Employee;
        return $"{_employee.Name} works as a {_employee.JobTitle}";
    }
}

what we did here is took that human parameter of type object and cast it as our relative objects, we then created a custom return string based on each type. 

class Program
{
    static void Main(string[] args)
    {
        var pd = new PersonDisplay();
        var sd = new StudentDisplay();
        var ed = new EmployeeDisplay();

        var people = new Person[] {
            new Person(pd, "Pawel Chooch"), new Person(pd, "Marin Smartzki"),
            new Student(sd, "Magda Tivonik", "Physics", "Math", "Chemestry" ),
            new Student(sd,"Jakub Tivonik", "Art", "English Lit", "Poetry" ),
            new Employee(ed, "Cezar Zenon", "Software Engineer")
        };

        foreach (var p in people)
            p.Display();
    }
}

in our main we then instantiate our three refined abstractions that inherit from our display abstraction and we pass them into our concrete classes.

using System;
using System.Linq;

namespace pc.patternBridge
{
    interface IPerson
    {
        string Name { get; set; }
        void Display();
    }

    abstract class Display
    {
        public abstract string Print(object human);
    }

    class Person : IPerson
    {
        Display _display;
        public string Name { get; set; }
        public Person(Display display) => _display = display;
        public Person(Display display, string name)
            : this(display) => Name = name;
        public void Display() => Console.WriteLine(_display?.Print(this));
    }

    class Student : Person
    {
        static int _runningID = 0;
        public int Id { get; set; } = _runningID++;
        public string[] Classes { get; private set; } = new string[6];
        public Student(Display display, string name, params string[] classes)
            : base(display, name) => Classes = classes;
    }

    class Employee : Person
    {
        static int _runningID = 0;
        public int Id { get; set; } = _runningID++;
        public string JobTitle { get; set; }
        public Employee(Display display, string name, string jobTitle)
            : base(display, name) => JobTitle = jobTitle;
    }

    class PersonDisplay : Display
    {
        public override string Print(object human)
        {
            var _person = human as Person;
            return $"Person: {_person.Name}";
        }
    }

    class StudentDisplay : Display
    {
        public override string Print(object human)
        {
            var _student = human as Student;
            var classes = _student.Classes.Aggregate((x, y) => $"{x}, {y}");
            return $"Student #:{_student.Id}; {_student.Name} is taking {classes}";
        }
    }

    class EmployeeDisplay : Display
    {
        public override string Print(object human)
        {
            var _employee = human as Employee;
            return $"{_employee.Name} works as a {_employee.JobTitle}";
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var pd = new PersonDisplay();
            var sd = new StudentDisplay();
            var ed = new EmployeeDisplay();

            var people = new Person[] {
                new Person(pd, "Pawel Chooch"), new Person(pd, "Marin Smartzki"),
                new Student(sd, "Magda Tivonik", "Physics", "Math", "Chemestry" ),
                new Student(sd,"Jakub Tivonik", "Art", "English Lit", "Poetry" ),
                new Employee(ed, "Cezar Zenon", "Software Engineer")
            };

            foreach (var p in people)
                p.Display();
        }
    }
}

now this has mostly been an exercise in exploring this pattern, one that seems very vague, confusing and poorly explained also i've never really seen or heard of it in use, however it does remind me of Inversion of control, which would explain why no one refers to this pattern. so for me i'm going to think of the bridge patter of basically IOC but with abstract classes instead of interfaces.