Monday 15 October 2018

Adapter Pattern

The adapter pattern is used to facilitate the use of an object inside of a component even if the component expects an interface that the object does not implement; to facilitate the component's use of the object, we can wrap the object in an adapter that implements the interface the component expects. let's take a look at some UML



In this situation let's say that we have instances of the person class, and we are using a HumanOutputer, now our HumanOutputer accepts objects that realize the IHuman interface which our Person objects are not. so what we do is create a PersonToHumanAdapter in the middle that has a Person and implements the IHuman interface and exposes what we need from the person class through that IHuman implementation.

Let's take a look at the code to get a better understanding of it

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime BirthDate { get; set; }

    public Person(string firstName, string lastName, DateTime birthDate)
    {
        FirstName = firstName;
        LastName = lastName;
        BirthDate = birthDate;
    }

}

This class simply represents a our person, now let's take a look at our HumanOutputter  class who's job is to take in an enumerable of humans and just print them to the console.

static class HumanOutputter
{
    public static void Write(IEnumerable<IHuman> humans)
    {
        foreach (var h in humans)
            Console.WriteLine($"{h.Name} ({h.Age})");
    }
}

now even without seeing the IHuman interface, it's pretty obvious that our Person model doesn't implement said interface, but we clearly have the information in our Person model that our HumanOutputter needs.

interface IHuman
{
    string Name { get; set; }
    int Age { get; }

}

In comes our PersonToHumanAdapter

class PersonToHumanAdaptorIHuman
{
    Person _person;
    public PersonToHumanAdaptor(Person person) => _person = person;
       
    public string Name {
        get => $"{_person.FirstName} {_person.LastName}";
        set {
            var fullName = value.Split(' ');
            _person.FirstName = fullName[0];
            _person.LastName = fullName[1];
        }
    }

    public int Age {
        get {
            var today = DateTime.Now;
            var age = today.Year - _person.BirthDate.Year;

            return _person.BirthDate > today.AddYears(-age) ? --age : age;
        }          

    }
}

now all our "Adapter" class does is takes in a person as a constructor variable and implements the IHuman interface, then uses the data in the Person field to surface the values that our Human outputter is going to need.

class Program
{
    static void Main(string[] args)
    {
        var People = new Person[] {
            new Person("Pawel", "Chooch", new DateTime(1984,1,31)),
            new Person("Marin", "Smatzki", new DateTime(1983,12,2)),
            new Person("Bob", "Smith", new DateTime(1985,7,21))
        };

        IEnumerable<IHuman> humans = People.Select(p => new PersonToHumanAdaptor(p));
        HumanOutputter.Write(humans);
    }

}

And that's basically the adapter pattern, it wraps objects so that they can be used by other components.

The adapter pattern can also be used when developing a framework to facilitate future compatibility. By leveraging the adapter pattern we facilitate the Open/Close principle of  the SOLID principles; being that our objects should be open to extension, but closed to modification.

Monday 8 October 2018

Command Pattern

The command (Action, Transaction) pattern is used to decouple logic; it allows you to encapsulate your "Action" within an object that your main client can call to execute. Something to keep in mind is that your command is entirely self sufficient, it really should rely on itself, with no arguments being passed from the calling object to the execute.

Commands can have execute and unexecute definitions, thus facilitating undo functionality. let's take a look at a simplified UML representation, the UML i'm using is tailored to my example.


now our invoker maintains a stack of commands that have been fired, this is then used by the undo method to undo whatever it is our command did. Our commands that can be undone are sent to our invoker via the ExecuteCommand method and of course we set our ListPeopleCommand through our constructor; the ListPeopleCommand is an exception, because it can't really be undone.

next let's focus on our ICommand interface it's concrete class and their relationships with the invoker; the ICommand interface simply defines an execute and an unexecute method, one does something, the other undoes that thing. it's really up to us to come up with the logic for both. Our concrete implementation of the ICommand Interface has a reference to a receiver, basically the thing our commands will be modifying. you can notice that it's only the concrete command class that knows anything about the receiver, and this facilitates our decoupling between the invoker and receiver.

First let's take a look at this person class

class Person
{
    static int runningId = 0;
    public int Id { get; private set; } = runningId++;
    public string Name { get; set; }
    public Person(string name) : base() => Name = name;
    public string Display() => $"{Id}) {Name}";

}

Not  exactly a brain buster, next let's take a look at our ICommand interface.

interface ICommand
{
    void Execute();
    void Unexecute();

}

Again nothing to it, just like the UML says two defined methods, next let's make things a bit interesting and take a look at our invoker class

class Invoker {
    Stack<ICommand> commandStack = new Stack<ICommand>();
    ICommand listPeopleCommand;

    public Invoker(ICommand listPeopleCommand) => this.listPeopleCommand = listPeopleCommand;

    public void ExecuteCommand(ICommand command) {
        commandStack.Push(command);
        commandStack.Peek().Execute();
    }

    public void ListPeople() => listPeopleCommand.Execute();

    public void Undo() {
        if (commandStack.Count > 0)
            commandStack.Pop().Unexecute();
        else
            Console.WriteLine("Nothing to undo");
    }

}

notice that we still haven't even mentioned a concrete implementation of our ICommand interface, the invoker wants ICommands, but is indifferent to their inner workings other than implementing the ICommand interface, nor does the invoker know or care about the receiver. Pay attention to the ExecuteCommand method, it pushes an ICommand onto our stack and executes the command, then our undo method does the opposite, pops an ICommand and calls it's unexecute method.

Next let's take a look at the ListPeopleCommand

class ListPeopleCommandICommand
{
    IList<Person> people;
    public ListPeopleCommand(IList<Person> People) => people = People;

    public void Execute()
    {
        Console.Clear();
        foreach (var person in people)
            Console.WriteLine($"\t{person.Display()}");
        Console.WriteLine();
    }

    public void Unexecute() { //do nothing; }

}

we looked at the ListPeopleCommand first because it doesn't require an unexecute implementation, but notice that it takes in a receiver, in this case a list of people.

Now let's take a look at the CreatePersonCommand

class CreatePersonCommandICommand
{
    IList<Person> people;
    Person person;
    public CreatePersonCommand(IList<Person> People) => people = People;

    public void Execute()
    {
        Console.WriteLine("\nEnter in the persons name");
        string name = null;
        while (String.IsNullOrEmpty(name = Console.ReadLine()));

        person = new Person(name);
        people.Add(person);
        Console.Clear();
        Console.WriteLine($"\tCreated:{person.Display()}");
    }

    public void Unexecute()
    {
        people.Remove(person);
        Console.WriteLine($"\tUndone:{person.Display()} creation");
    }

}

Again our command takes in a reference to our receiver, notice that our command maintains a reference to the person we create outside of the Execute method's scope, this is so that our unexecute method can remove that person from our people list.

next lets' create UpdatePersonCommand, and DeletePersonCommand.

class UpdatePersonCommandICommand
{
    IList<Person> people;
    string oldName;
    Person person;
  
    public UpdatePersonCommand(IList<Person> People) => people = People;

    public void Execute()
    {
        Console.WriteLine("\nEnter in the id of the person who's name you want to update");
        int personId = -1;
        while (!int.TryParse(Console.ReadKey().KeyChar.ToString(), out personId));

        Console.WriteLine("\nEnter in the new name of the person to update");
        string newName = null;

        while (String.IsNullOrEmpty(newName = Console.ReadLine()));

        person= people.FirstOrDefault(p => p.Id == personId);
        oldName = person.Name;
        Console.Clear();
        Console.Write($"{person.Display()} to ");

        person.Name = newName;
        Console.WriteLine(person.Name);
    }

    public void Unexecute()
    {
        Console.Write($"undone rename {person.Name} ");
        person.Name = oldName;
        Console.WriteLine($"back to {oldName}");
    }
}

class DeletePersonCommandICommand
{
    IList<Person> people;

    Person person;
    public DeletePersonCommand(IList<Person> People) => people = People;

    public void Execute()
    {
        Console.WriteLine("\nEnter in the id of the person who you want to delete");

        int personId = -1;
        while (!int.TryParse(Console.ReadKey().KeyChar.ToString(), out personId));

        person = people.FirstOrDefault(p => p.Id == personId);
        Console.Clear();
        Console.WriteLine($"\tRemoved:{person.Display()}\r\n");

        people.Remove(person);
    }

    public void Unexecute()
    {
        people.Add(person);
        Console.WriteLine($"undone delete: added person {person.Display()} back");
    }

}

they both follow a similar pattern as our CreatePersonCommand just with varying logic. next lets take a look at our main

class Program
{
    static void Main(string[] args)
    {
        var selection = -1;
        var people = new List<Person>(); /* Receiver */
        var invoker = new Invoker(new ListPeopleCommand(people));

        do
        {
            switch (selection)
            {
                case 1:
                    invoker.ExecuteCommand(new CreatePersonCommand(people));
                    break;
                case 2:
                    invoker.ExecuteCommand(new UpdatePersonCommand(people));
                    break;
                case 3:
                    invoker.ExecuteCommand(new DeletePersonCommand(people));
                    break;
                case 4:
                    invoker.ListPeople();
                    break;
                case 9:
                    invoker.Undo();
                    break;
            }

            ListCommands();

            while (!int.TryParse(Console.ReadKey().KeyChar.ToString(), out selection));

        } while (selection > 0);

    }

    static void ListCommands()
    {
        Console.WriteLine("1) Add person");
        Console.WriteLine("2) Update person");
        Console.WriteLine("3) Delete person");
        Console.WriteLine("4) List people");
        Console.WriteLine("9) undo");
        Console.WriteLine("0) Exit");
    }

}

as you can see it's actually pretty straight forward, pay attention to the instantiation of our invoker, we pass in our ListPeopleCommand, then in our application logic we simply call the defined ListPeople method defined in our Invoker, same goes for the Undo Method, just calling it on the invoker. the neat thing is the undo-able commands where we pass new instances of them to the Invoker via the ExecuteCommand(command:ICommand) method.

with this approach we can easily execute commands and undo them.

a quick caveat is that the app itself is very brittle there's almost no preventative measures in place so if you try to delete or edit an item that's not there well the app will crash.

here's the full code from start to finish.

using System;
using System.Collections.Generic;
using System.Linq;

namespace pav.commandPattern
{
    class Person
    {
        static int runningId = 0;
        public int Id { get; set; } = runningId++;
        public string Name { get; set; }
        public Person(string name) : base() => Name = name;
        public string Display() => $"{Id}) {Name}";
    }

    interface ICommand
    {
        void Execute();
        void Unexecute();
    }

    class CreatePersonCommand : ICommand
    {
        IList<Person> people;
        Person person;

        public CreatePersonCommand(IList<Person> People) => people = People;

        public void Execute()
        {
            Console.WriteLine("\nEnter in the persons name");
            string name = null;
            while (String.IsNullOrEmpty(name = Console.ReadLine()));
            person = new Person(name);
            people.Add(person);
            Console.Clear();
            Console.WriteLine($"\tCreated:{person.Display()}");
        }

        public void Unexecute()
        {
            people.Remove(person);
            Console.WriteLine($"\tUndone:{person.Display()} creation");
        }
    }

    class UpdatePersonCommand : ICommand
    {
        //reciever
        IList<Person> people;

        string oldName;
        Person person;

        public UpdatePersonCommand(IList<Person> People) => people = People;

        public void Execute()
        {
            Console.WriteLine("\nEnter in the id of the person who's name you want to update");
            int personId = -1;
            while (!int.TryParse(Console.ReadKey().KeyChar.ToString(), out personId));

            Console.WriteLine("\nEnter in the new name of the person to update");
            string newName = null;

            while (String.IsNullOrEmpty(newName = Console.ReadLine()));

            person = people.FirstOrDefault(p => p.Id == personId);
            oldName = person.Name;
            Console.Clear();
            Console.Write($"{person.Display()} to ");

            person.Name = newName;
            Console.WriteLine(person.Name);
        }

        public void Unexecute()
        {
            Console.Write($"undone rename {person.Name} ");
            person.Name = oldName;
            Console.WriteLine($"back to {oldName}");
        }
    }

    class DeletePersonCommand : ICommand
    {
        IList<Person> people;

        Person person;
        public DeletePersonCommand(IList<Person> People) => people = People;

        public void Execute()
        {
            Console.WriteLine("\nEnter in the id of the person who you want to delete");

            int personId = -1;
            while (!int.TryParse(Console.ReadKey().KeyChar.ToString(), out personId));

            person = people.FirstOrDefault(p => p.Id == personId);
            Console.Clear();
            Console.WriteLine($"\tRemoved:{person.Display()}\r\n");

            people.Remove(person);
        }

        public void Unexecute()
        {
            people.Add(person);
            Console.WriteLine($"undone delete: added person {person.Display()} back");
        }
    }

    class ListPeopleCommand : ICommand
    {
        IList<Person> people;

        public ListPeopleCommand(IList<Person> People) => people = People;

        public void Execute()
        {
            Console.Clear();
            Console.WriteLine("\nPeople");

            foreach (var person in people)
                Console.WriteLine($"\t{person.Display()}");
            Console.WriteLine();
        }

        public void Unexecute() {/*do nothing*/}
    }

    class Invoker
    {
        Stack<ICommand> commandStack = new Stack<ICommand>();
        ICommand ListPeopleCommand;
        public Invoker(ICommand listPeopleCommand) => ListPeopleCommand = listPeopleCommand;

        public void ExecuteCommand(ICommand command)
        {
            commandStack.Push(command);
            commandStack.Peek().Execute();
        }

        public void ListPeople() => ListPeopleCommand.Execute();

        public void Undo()
        {
            if (commandStack.Count > 0)
                commandStack.Pop().Unexecute();
            else
                Console.WriteLine("Nothing to undo");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var selection = -1;
            var people = new List<Person>(); /* Receiver */
            var invoker = new Invoker(new ListPeopleCommand(people));

            do
            {
                switch (selection)
                {
                    case 1:
                        invoker.ExecuteCommand(new CreatePersonCommand(people));
                        break;
                    case 2:
                        invoker.ExecuteCommand(new UpdatePersonCommand(people));
                        break;
                    case 3:
                        invoker.ExecuteCommand(new DeletePersonCommand(people));
                        break;
                    case 4:
                        invoker.ListPeople();
                        break;
                    case 9:
                        invoker.Undo();
                        break;
                }

                ListCommands();

                while (!int.TryParse(Console.ReadKey().KeyChar.ToString(), out selection));

            } while (selection > 0);

        }

        static void ListCommands()
        {
            Console.WriteLine("1) Add person");
            Console.WriteLine("2) Update person");
            Console.WriteLine("3) Delete person");
            Console.WriteLine("4) List people");
            Console.WriteLine("9) undo");
            Console.WriteLine("0) Exit");
        }
    }
}