Chain of Responsibility Pattern

This type of pattern falls in the behavioural design patterns category. It is a design pattern where a sender sends a request to a chain of objects, the sender does not know which object in the chain will handle the request and the objects in the chain decide themselves who to honour the request. Every object in the chain has the responsibility to decide the request, if they cannot serve the request then it may forward it to the next node in the chain, hence the chain of responsibility. This pattern of delegation is often encountered in the real world where there’s one interface for the client (sender) to go through. A good example is a loan application where your loan request may be channeled and handled by one particular department. Another concrete example is an expenses/requisitions request approval in a company setup where each head of department has the approval authority and depending on the value of the expense/requisition, his authority may approve the request or forward it to the next authority in the chain. Other good examples which come to mind are Coin sorting machine, rank poker hands and ATM money dispensers.

Now let’s see how we might implement the Chain of Responsibility with some code example. Let’s use expenses/requisitions request approval explained above. We’ll start by defining our Requisition interface, which simply has the Amount property (the requisition value)


public interface IRequisition
{
    Decimal Amount { get; }
}

Its concrete implementation is as follows


public class Requisition : IRequisition
{
    public Requisition(Decimal amount) {
        Amount = amount;
    }

    public Decimal Amount { get; private set; }
}

For the requisition approval authority, an employee who has the responsibility to approve a requisition

public interface IRequisitionApprover
{
    ApprovalResponse ApproveRequisition(IRequisition requisition);
}

public enum ApprovalResponse
{
    Denied,
    Approved,
    BeyondApprovalLimit,
}

The implementation follows:

public class Employee : IRequisitionApprover
{
    public Employee(string name, Decimal approvalLimit)
	{
		Name = name;
		this.approvalLimit = approvalLimit;
	}

	public string Name { get; private set; }

	public ApprovalResponse ApproveExpense(IRequisition requisition)
	{
		return (requisition.Amount > _approvalLimit)
			? ApprovalResponse.BeyondApprovalLimit: ApprovalResponse.Approved;
	}

	private readonly Decimal approvalLimit;
}

Next we define the RequisitionHandler class which represents a single link in the chain of responsibility

public interface IRequisitionHandler
{
	ApprovalResponse Approve(IRequisition requisition);
	void RegisterNext(IRequisitionHandler next);
}

public class RequisitionHandler: IRequisitionHandler
{
	public ExpenseHandler(IRequisitionApprover requisitionApprover)
	{
		approver = requisitionApprover;
		next = EndOfChainExpenseHandler.Instance;
	}

	public ApprovalResponse Approve(IRequisition requisition)
	{
		ApprovalResponse response = approver.ApproveExpense(requisition);
		if(response == ApprovalResponse.BeyondApprovalLimit)
		{
			return next.Approve(requisition);
		}

		return response;
	}

	// Register the next link in the chain i.e. if the current handler
	// cannot approve the requisition request then forward it to the next node in the chain
	public void RegisterNext(IRequisitionHandler next)
	{
		this.next = next;
	}

	private readonly IRequisitionApprover approver;
	private IRequisitionHandler next;
}

We need to define an end of chain handler that handles requisition values beyond the approval limit of the last member of the chain, this class exposes a singleton instance

class EndOfChainRequisitionHandler : IRequisitionHandler
{
    private EndOfChainRequisitionHandler() { }
    public static EndOfChainRequisitionHandler Instance
	{
		get { return instance; }
	}

	public ApprovalResponse Approve(IExpenseReport expenseReport)
	{
		// return denied, always and only since we've made it to this point and nobody has
		// approved the requisition and we shouldn't approve it here
		return ApprovalResponse.Denied;
	}

	public void RegisterNext(IExpenseHandler next)
	{
		throw new InvalidOperationException("End of chain handler must be the end of the chain!");
	}

	private static readonly EndOfChainRequisitionHandler instance = new EndOfChainRequisitionHandler();
}

For the application logic

class Approval
{
	static void Main()
	{
		RequisitionHandler josh = new RequisitionHandler(new Employee("Josh SeniorDeveloper", Decimal.Zero));
		RequisitionHandler scott = new RequisitionHandler(new Employee("Scott LineManager", new Decimal(1000)));
		RequisitionHandler rudo = new RequisitionHandler(new Employee("Rudo ViceChair", new Decimal(5000)));
		RequisitionHandler chris = new RequisitionHandler(new Employee("Chris Chairman", new Decimal(20000)));

		josh.RegisterNext(scott);
		scott.RegisterNext(rudo);
		rudo.RegisterNext(chris);

		Decimal requisitionAmount;
		if (ConsoleInput.TryReadDecimal("Expense requisition amount:", out requisitionAmount))
		{
			// Create a requisition object
			IRequisition requisition = new Requisition(requisitionAmount);

			// Got to the head of the chain Josh and ask if he can approve this requisition
			ApprovalResponse response = josh.Approve(requisition);

			Console.WriteLine("The request was {0}.", response);

			Console.ReadKey();
		}
	}
}

Helper class

public static class ConsoleInput
{
	public static bool TryReadDecimal(string prompt, out Decimal value)
	{
		value = default(Decimal);

		while (true)
		{
			Console.WriteLine(prompt);
			string input = Console.ReadLine();
			if (string.IsNullOrEmpty(input))
			{
				return false;
			}

			try
			{
				value = Convert.ToDecimal(input);
				return true;
			}
			catch (FormatException)
			{
				Console.WriteLine("The input is not a valid decimal.");
			}
			catch (OverflowException)
			{
				Console.WriteLine("The input is not a valid decimal.");
			}
		}
	}
}

Single Responsibility Pattern

In my quest for effortful study and learning new skills in software development, I purchased the Robert C. Martin Series book “Agile Principles, Patterns and Practices in C#” which I must say contains effulgent content every C# developer needs to know. In the past I have struggled with grasping software practice principles but this book really helps me in lessening that burden by providing succinct, clear and solid introduction to various agile methods – both coding principles as well as agile processes. Among these principles, one seems very simple but is hard to get right (as Robert C. Martin puts it). It’s the first principle of SOLID (Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion, a mnemonic acronym orchestrated by Michael Feathers for the “first five principles” identified by Robert C. Martin) and also one of the oldest principles of software development: the Single Responsibility Principle (SRP). It states that there should never be more than one reason for a class to change. That is, every class should have only one responsibility  Everything in the class should be related to that single purpose. It does not mean that your classes should only contain one method or property. There may be many members as long as they relate to the single responsibility. It may be that when the one reason to change occurs, multiple members of the class may need modification. It may also be that multiple classes will require updates.

Example Code

To demonstrate the application of the SRP, we consider an Order class that exposes a problem with too many responsibilities thereby violating the SRP and explain how it can be refactored to comply with the principle:


    public class Order
    {
        public void Checkout(Cart cart, PaymentDetails paymentDetails, bool notifyCustomer)
        {
            if (paymentDetails.PaymentMethod == PaymentMethod.CreditCard)
            {
                ChargeCard(paymentDetails, cart);
            }

            ReserveInventory(cart);

            if(notifyCustomer)
            {
                NotifyCustomer(cart);
            }
        }

        public void NotifyCustomer(Cart cart)
        {
            string customerEmail = cart.CustomerEmail;
            if (!String.IsNullOrEmpty(customerEmail))
            {
                using (var message = new MailMessage("orders@somewhere.com", customerEmail))
                using (var client = new SmtpClient("localhost"))
                {
                    message.Subject = "Your order placed on " + DateTime.Now.ToString();
                    message.Body = "Your order details: \n " + cart.ToString();

                    try
                    {
                        client.Send(message);
                    }
                    catch (Exception ex)
                    {
                        Logger.Error("Problem sending notification email", ex);
                    }
                }
            }
        }

        public void ReserveInventory(Cart cart)
        {
            foreach(var item in cart.Items)
            {
                try
                {
                    var inventorySystem = new InventorySystem();
                    inventorySystem.Reserve(item.Sku, item.Quantity);

                }
                catch (InsufficientInventoryException ex)
                {
                    Logger.Error("Insufficient inventory for item " + item.Sku, ex);
                }
                catch (Exception ex)
                {
                    Logger.Error("Problem reserving inventory", ex);
                }
            }
        }

        public void ChargeCard(PaymentDetails paymentDetails, Cart cart)
        {
            using (var paymentGateway = new PaymentGateway())
            {
                try
                {
                    paymentGateway.Credentials = "account credentials";
                    paymentGateway.CardNumber = paymentDetails.CreditCardNumber;
                    paymentGateway.ExpiresMonth = paymentDetails.ExpiresMonth;
                    paymentGateway.ExpiresYear = paymentDetails.ExpiresYear;
                    paymentGateway.NameOnCard = paymentDetails.CardholderName;
                    paymentGateway.AmountToCharge = cart.TotalAmount;

                    paymentGateway.Charge();
                }
                catch (AvsMismatchException ex)
                {
                    Logger.Error("The card gateway rejected the card based on the address provided.", ex);
                }
                catch (Exception ex)
                {
                    Logger.Error("There was a problem with your card.", ex);
                }
            }
        }
    }

As you can notice above, the Order class is part of an eCommerce Retail PoS application that supports a number of operations which include Checkout, ChargeCard, NotifyCustomer and ReserveInventory. Most of the work is carried out in the Checkout method, which first checks to see if the payment method is a Credit Card then charge the card using the payment details provided. Once this goes through, the inventory is reserved and finally if the customer has set to be notified of the transaction, the NotifyCustomer method then notify the customer that the cart was processed.

The above said methods have some dependencies; the NotifyCustomer depends on the SMTP Email, ReserveInventory uses the InventorySystem service and ChargeCard is using a payment gateway to actually charge the card.

Besides the many responsibility coupling above, one can easily see a recipe for disaster with the above in that any change to notifications, credit card processing or inventory management will affect any implementations of the Order class.

Refactored Code

To refactor the code, we need to make a judgment call where the responsibilities/behavior possibly change independently in the future, which behaviour is co-dependent on the other and will always change at the same time (“coupling”) and which behaviour will never change in the first place. In the above Order Class, we notice that the Checkout method has three main actions; processing payment, reserving inventory and notifying the customer. We can split these actions into separate interfaces IPaymentProcessor, IReservationService and INotificationService with their respective operations ProcessCreditCard, ReserveInventory and NotifyCustomerOrderCreated. The eCommerce Retail PoS application can handle different types of Orders, which can be a PoS Credit Order which can have dependencies on the refactored interfaces or the PoS Cash Order which does not have any dependency on the above as none of them are concerns of a cash transaction of the PoS:

    public abstract class Order
    {
        protected readonly Cart _cart;

        protected Order(Cart cart)
        {
            _cart = cart;
        }

        public virtual void Checkout()
        {
            // log the order in the database
        }
    }

    public class OnlineOrder : Order
    {
        private readonly INotificationService _notificationService;
        private readonly PaymentDetails _paymentDetails;
        private readonly IPaymentProcessor _paymentProcessor;
        private readonly IReservationService _reservationService;

        public OnlineOrder(Cart cart, PaymentDetails paymentDetails)
            : base(cart)
        {
            _paymentDetails = paymentDetails;
            _paymentProcessor = new PaymentProcessor();
            _reservationService = new ReservationService();
            _notificationService = new NotificationService();
        }

        public override void Checkout()
        {
            _paymentProcessor.ProcessCreditCard(_paymentDetails, _cart.TotalAmount);

            _reservationService.ReserveInventory(_cart.Items);

            _notificationService.NotifyCustomerOrderCreated(_cart);

            base.Checkout();
        }
    }

    public class PoSCreditOrder : Order
    {
        private readonly PaymentDetails _paymentDetails;
        private readonly IPaymentProcessor _paymentProcessor;

        public PoSCreditOrder(Cart cart, PaymentDetails paymentDetails)
            : base(cart)
        {
            _paymentDetails = paymentDetails;
            _paymentProcessor = new PaymentProcessor();
        }

        public override void Checkout()
        {
            _paymentProcessor.ProcessCreditCard(_paymentDetails, _cart.TotalAmount);

            base.Checkout();
        }
    }

    public class PoSCashOrder : Order
    {
        public PoSCashOrder(Cart cart)
            : base(cart)
        {
        }
    }

    #region PaymentProcessor

    public interface IPaymentProcessor
    {
        void ProcessCreditCard(PaymentDetails paymentDetails, decimal amount);
    }

    internal class PaymentProcessor : IPaymentProcessor
    {
        public void ProcessCreditCard(PaymentDetails paymentDetails, decimal amount)
        {
            throw new NotImplementedException();
        }
    }

    #endregion

    #region ReservationService

    public interface IReservationService
    {
        void ReserveInventory(IEnumerable<OrderItem> items);
    }

    public class ReservationService : IReservationService
    {
        public void ReserveInventory(IEnumerable<OrderItem> items)
        {
            throw new NotImplementedException();
        }
    }

    #endregion

    #region NotificationService

    internal interface INotificationService
    {
        void NotifyCustomerOrderCreated(Cart cart);
    }

    internal class NotificationService : INotificationService
    {
        public void NotifyCustomerOrderCreated(Cart cart)
        {
            throw new NotImplementedException();
        }
    }

    #region Cart

    public class Cart
    {
        public decimal TotalAmount { get; set; }
        
        public IEnumerable<OrderItem> Items { get; set; }

        public string CustomerEmail { get; set; }
    }

    public class OrderItem
    {
        public string Sku { get; set; }
        
        public int Quantity { get; set; }
    }

   #endregion

As Robert C Martin would point out, if two responsibilities are always expected to change at the same time then there’s no need to separate them into different classes, consequently this would result into a smell of Needless Complexity. The same is the case for responsibilities that never change – the behaviour is invariant, and there is no need to split it.

Regex based string maniuplation

Oh, the joys of Regex! I was faced with a simple issue which involved manipulating a string of the form “Address1, Address2, Street, City, PostCode” so that it can be split into a multiline. The bug was strangely displaying the “Address 2” data twice in the multiline array. Initially the LINQ lambda query was being mapped into an array by the ToArray() method and then iterating over the array to display each line of text within an asp literal control:


string[] addressArray = l_event.Location.Split(',').Where(s => !s.Trim().Equals(string.Empty)).ToArray();
foreach (string line in addressArray)
{
     litLocation.Text += line;
     litLocation.Text += " ";
}

I had almost given up hope fixing the above issue when I decided to try a regex based solution which magically solved this:

litLocation.Text = Regex.Replace(l_event.Location.Trim(','), @"(\s*,\s*)", " ").Trim(',');