Monday, 2 March 2020

C# - Design Pattern - Chain Of Responsibility

Example 1

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

namespace ChainOfResponsibility
{
    public interface IHandler
    {
        IHandler SetNext(IHandler handler);

        object Handle(object request);
    }

    abstract class BoilerAbstractHandler : IHandler
    {
        private IHandler _nextHandler;

        public IHandler SetNext(IHandler handler)
        {
            this._nextHandler = handler;
           
            return handler;
        }

        public virtual object Handle(object request)
        {
            if (this._nextHandler != null)
            {
                return this._nextHandler.Handle(request);
            }
            else
            {
                return null;
            }
        }
    }

    class BoilerOneHandler : BoilerAbstractHandler
    {
        public override object Handle(object request)
        {
            if ((request as string) == "MILK")
            {
                return $"Adding {request.ToString()}.\n";
            }
            else
            {
                return base.Handle(request);
            }
        }
    }

    class BoilerTwoHandler : BoilerAbstractHandler
    {
        public override object Handle(object request)
        {
            if (request.ToString() == "SUGAR")
            {
                return $"Adding {request.ToString()}.\n";
            }
            else
            {
                return base.Handle(request);
            }
        }
    }

    class BoilerThreeHandler : BoilerAbstractHandler
    {
        public override object Handle(object request)
        {
            if (request.ToString() == "BUTTER")
            {
                return $"Adding {request.ToString()}.\n";
            }
            else
            {
                return base.Handle(request);
            }
        }
    }

    class Client
    {
        public static void ClientCode(BoilerAbstractHandler handler)
        {
            foreach (var ingredient in new List<string> { "MILK", "SUGAR", "BUTTER" })
            {               

                var result = handler.Handle(ingredient);

                if (result != null)
                {
                    Console.Write($" {result}");
                }
                else
                {
                    Console.WriteLine($" {ingredient} was added.");
                }
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var BoilerOne = new BoilerOneHandler();
            var BoilerTwo = new BoilerTwoHandler();
            var BoilerThree = new BoilerThreeHandler();

            BoilerOne.SetNext(BoilerTwo).SetNext(BoilerThree);

            Console.WriteLine("Chain: BoilerOne > BoilerTwo > BoilerThree\n");
            Client.ClientCode(BoilerOne);
            Console.WriteLine();

            Console.WriteLine("Subchain: BoilerTwo > BoilerThree\n");
            Client.ClientCode(BoilerTwo);
        }
    }
}


Example 2

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

namespace ChainOfResponsibility01
{
    public class LoanEventArgs : EventArgs
    {
        internal Loan Loan { get; set; }
    }

    /// The 'Handler' abstract class
    abstract class Approver
    {
        // Loan event
        public EventHandler<LoanEventArgs> Loan;

        // Loan event handler
        public abstract void LoanHandler(object sender, LoanEventArgs e);

        // Constructor
        public Approver()
        {
            Loan += LoanHandler;
        }

        public void ProcessRequest(Loan loan)
        {
            OnLoan(new LoanEventArgs { Loan = loan });
        }

        // Invoke the Loan event
        public virtual void OnLoan(LoanEventArgs e)
        {
            if (Loan != null)
            {
                Loan(this, e);
            }
        }

        // Sets or gets the next approver
        public Approver Successor { get; set; }
    }

    /// The 'ConcreteHandler' class
    class Clerk : Approver
    {
        public override void LoanHandler(object sender, LoanEventArgs e)
        {
            if (e.Loan.Amount < 25000.0)
            {
                Console.WriteLine("{0} approved request# {1}",
                this.GetType().Name, e.Loan.Number);
            }
            else if (Successor != null)
            {
                Successor.LoanHandler(this, e);
            }
        }
    }

    /// The 'ConcreteHandler' class
    class AssistantManager : Approver
    {
        public override void LoanHandler(object sender, LoanEventArgs e)
        {
            if (e.Loan.Amount < 45000.0)
            {
                Console.WriteLine("{0} approved request# {1}",
                this.GetType().Name, e.Loan.Number);
            }
            else if (Successor != null)
            {
                Successor.LoanHandler(this, e);
            }
        }
    }

    /// The 'ConcreteHandler' clas
    class Manager : Approver
    {
        public override void LoanHandler(object sender, LoanEventArgs e)
        {
            if (e.Loan.Amount < 100000.0)
            {
                Console.WriteLine("{0} approved request# {1}",
                sender.GetType().Name, e.Loan.Number);
            }
            else if (Successor != null)
            {
                Successor.LoanHandler(this, e);
            }
            else
            {
                Console.WriteLine(
                "Request# {0} requires an executive meeting!",
                e.Loan.Number);
            }
        }
    }

    class Loan
    {
        public double Amount { get; set; }
        public string Purpose { get; set; }
        public int Number { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Setup Chain of Responsibility
            Approver David = new Clerk();
            Approver George = new AssistantManager();
            Approver Nicky = new Manager();

            David.Successor = George;
            George.Successor = Nicky;

            // Generate and process loan requests
            var loan = new Loan { Number = 2034, Amount = 24000.00, Purpose = "Laptop Loan" };
            David.ProcessRequest(loan);

            loan = new Loan { Number = 2035, Amount = 42000.10, Purpose = "Bike Loan" };
            George.ProcessRequest(loan);

            loan = new Loan { Number = 2036, Amount = 156200.00, Purpose = "House Loan" };
            George.ProcessRequest(loan);

            // Wait for user
            Console.ReadKey();
        }
    }
}


//EnteringData
//Collecting
//Sorting
//Bucketing
//Cleansing

//ProperFormatting

1 comment: