Archive for October, 2015

CORAndUnityIoC

Author: Cole Francis, Architect


BACKGROUND

The Chain-of-Responsibility design pattern is a rather obscure behavioral pattern that is useful for creating workflows within a solution. Despite its obscurity, it happens to be one of my favorite all-time design patterns. The pattern chains the concrete handling classes together through a common chaining mechanism (some architects and developers also refer to this as the command class), passing a common request payload to each class through a succession pipeline until it reaches a class that is able to act upon the request.

I have personally and successfully architected a solution using this design pattern for a large and well-branded U.S. retail company. The solution is responsible for printing sale signs in well over a thousand stores across the United States, saving my client approximately $10 million dollars a year, year-over-year. From a development perspective, leveraging this design pattern made it easy to isolate the various units of the workflow, simplifying the process of assigning my various team members to the discrete pieces of functionality that were exposed as a result of using this behavioral design pattern.

While I am unable to discuss anything further about my previous personal experiences with this client, I am able to demonstrate a working example of this design pattern and focus on a business problem that is completely unrelated to anything I’ve done in the past. So, without further adieu, allow me introduce a fictitious business problem to you.


THE BUSINESS PROBLEM

A local transport company manages a fleet of 3 trucks and delivers locally made engines to different distribution centers across the Midwest. Here are the cargo hold specifications for their three delivery trucks:

  • Truck 1: (max load 5,000 lbs. and is used only to haul Red Engines)
  • Truck 2: (max load 6,000 lbs. and is used only to haul Yellow Engines)
  • Truck 4: (max load 6,500 lbs. and is used only to haul Blue Engines)

The company that manufactures these engines also ships their products locally to the T.H.E. Truck King Trucking Company warehouse for storage and distribution. After it’s all said and done, the dimensions of the boxed engines are all the same (42”Wx50”Lx 36”H), but the engine weights and locations the engines get shipped to vary significantly:

  • Red Engines: 532 lbs. each (only get shipped to Chicago, IL; Model Number#: R1773456935)
  • Blue Engines: 1,386 lbs. each (only get shipped to Overland Park, KS; Model Number#: B8439845841)
  • Yellow Engines: 1,783 lbs. each (only get shipped to Des Moines, IA; Model Number#: Y4833345760)

Here are some other things the client brings up during your conversation with them:

  • The crates the engines are transported on are very durable and allow for the engines to be stacked on top of each other during transport, which means each truck will reach its maximum weight load well before it runs out of space.
  • As pointed out above, specific engine types get shipped to specific locations.
  • Occasionally engines are put in the wrong trucks, as loaders are very busy and are working strictly from memory. When this occurs, it’s a miserable experience for everyone.
  • Sometimes the trucks aren’t filled to capacity, causing them to operate well below their maximum load. When this occurs, shipping and other operational costs skyrocket, causing us to lose money.
  • The loading crew has been notified of these issues, but mistakes continue to be made.
  • The larger distribution centers we ship to have stated that if the problem isn’t resolved soon, they will cancel our contract and look for a more reliable and efficient transport company.
  • We need a solution that tells our loading crew what truck to load the engine on, as well as something that tells them whether or not the truck is filled to maximum capacity from a maximum weight load standpoint.
  • The engine manufacturing company doesn’t plan to produce any other types of engines in the near future, but there is a possibility they may want to have more than one type of engine distributed to each of the three distribution points. There are no firm arrangements for this to happen yet, but the solution that is put into place must take this into account.


THE SOLUTION

Because we know the dimensions of each truck’s cargo hold, as well as the weight and dimensions of each product being shipped, the solution should be architected to allow a handler to determine the best course of action for the request it is handling. This is similar to the shipping company allowing the handlers of the crates to determine which trucks the different products should be loaded into.

However, instead of allowing a single entity to make this type of determination, we’ll decouple this association and allow the decision pattern to pass through a chain of inspecting classes, forcing the responsibility of determining whether or not it is capable of handling the request onto the class itself. If the class determines it cannot handle the request, then it will pass the request onto the next handler, who will then decide whether or not it is able to handle the request. This process will continue until we’ve exhausted every available concrete handling class.

By architecting the solution in this manner, we’re fairly sure that we’ll be able to meet all of the functional requirements articulated to us by our client.

The Chain of Responsibility (CoR) Pattern

CoR

Given the previous requirements, one great pattern that allows an object to pass along a chain of handlers until a handler determines it is capable of handling the request is known as the “Chain of Responsibility Handler”, or the CoR Pattern. Unlike a Mediator/Observer patter, CoR doesn’t maintain a link between the handlers in the chain, which is why CoR stands out from other patterns, making the sender and the receiver completely decoupled and allowing each handler to maintain its own set of standards and separation of concerns, making it a true object oriented workflow pattern.

Another great aspect beheld in this pattern is that there very little logic in the sender, beyond setting up the successive chain of concrete handlers. What’s more, the sender isn’t tasked with interrogating the request before making a request to handler. It merely chains the concrete handlers together and allows them figure out the rest, with each concrete handler being responsible for its own separate criteria and concern.


CoR PATTERN CLASSES AND OBJECTS

The classes and objects participating in this pattern are:

  1. The Handler Class (Handler Interface):
    1. An inheritable class used to:
      i. Create an interface used to handle requests.
      ii. Sets the successor used to interact with the next concrete method.
      iii. Implements the successor link in the chain.
  2. The ConcreteHandler Class (Handler)
    1. Interrogates the request and determine whether or not it can act upon the information.
    2. If it can’t access the request, then it forwards the request to the next handler (aka the successor).
  3. The Sender Class (Messenger)
    1. The Sender Class can either be a client application that establishes the successive order of the ConcreteHandler Classes, or
    2. The Sender Class can be a concrete class that acts autonomously of the client to establish the successive order of the ConcreteHandler classes and then acts upon them.


THE HANDLER CLASS

We’ll start out with the creation of the handler class. As pointed out in the summary of the code and description in the previous section, the Handler Class is responsible for assigning the next successor concrete class in a chain of classes that we’ll set up in just as bit.

using System;
using THE_TruckKing.Interfaces;

namespace THE_TruckKing
{
    /// <summary>
    /// The handler class assigns the next successor if the preceding class returns successfully
    /// This is the underlying key to the success of the 'Chain of Responsibility Pattern'
    /// </summary>
    /// 
    public abstract class Handler
    {
        protected Handler successor;

        public abstract IEngine HandleRequest(IEngine engine);

        public void SetSuccessor(Handler successor)
        {
            this.successor = successor;
        }
    }
}


THE CONCRETE CLASSES (THIS CAN BE BASED ON SUBJECT OR FUNCTION)

Next, we’ll implement the concrete handlers, inherit from the handler class, as well as act upon the request message. Here is the concrete handler for the blue engines.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using THE_TruckKing.Utilities;
using THE_TruckKing.Interfaces;

namespace THE_TruckKing
{
    /// <summary>
    /// Handles blue engine shipments to Overland Park, KS
    /// </summary>
    /// 
    public class ShipmentHandlerBlue : Handler
    {
        public override IEngine HandleRequest(IEngine engine)
        {
            int totalQuantityShippingHold = 0;
            int totalReturnToStock = 0;

            if (engine.Type == Constants.Engines.BLUE_ENGINE)
            {
                for (int i = 0; i < engine.QuantityShipping; i++)
                {
                    if (Constants.Engine_MAX_Weights.BLUE_ENGINE >=
                        ((engine.TotalQuantityShipping + 1) * Constants.Engine_Base_Weights.BLUE_ENGINE))
                    {
                        engine.TotalQuantityShipping += 1;
                        totalQuantityShippingHold += 1;
                    }
                    else
                    {
                        totalReturnToStock += 1;
                    }
                }

                Console.WriteLine(string.Format("Load {0} blue engine(s) on the truck destined for {1}",
                    totalQuantityShippingHold, Constants.Trucks_Destinations.BLUE_TRUCK));
                Console.WriteLine("");

                if (totalReturnToStock > 0)
                {
                    Console.WriteLine(string.Format("{0} of the {1} yellow engine(s) exceed load capacity. Please return them to stock", 
                        totalReturnToStock.ToString(), engine.QuantityShipping.ToString()));
                    Console.WriteLine("");
                }
            }
            else
            {
                successor.HandleRequest(engine);
            }

            return engine;
        }
    }
}

Continuing the successor chain, we’ll now implement the concrete handler class for the yellow engines. If the previous concrete handler can’t handle the request, then the blue class will then be responsible for determining whether or not it can. As you can see, the pattern follows the exact same pattern as the blue engine concrete handler.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using THE_TruckKing.Utilities;
using THE_TruckKing.Interfaces;

namespace THE_TruckKing
{
    /// <summary>
    /// Handles yellow engine shipments to Chicago, IL
    /// </summary>
    /// 
    public class ShipmentHandlerRed : Handler
    {
        public override IEngine HandleRequest(IEngine engine)
        {
            int totalQuantityShippingHold = 0;
            int totalReturnToStock = 0;

            if (engine.Type == Constants.Engines.RED_ENGINE)
            {
                for (int i = 0; i < engine.QuantityShipping; i++)
                {
                    if (Constants.Engine_MAX_Weights.RED_ENGINE >=
                        ((engine.TotalQuantityShipping + 1) * Constants.Engine_Base_Weights.RED_ENGINE))
                    {
                        engine.TotalQuantityShipping += 1;
                        totalQuantityShippingHold += 1;
                    }
                    else
                    {
                        totalReturnToStock += 1;
                    }
                }

                Console.WriteLine(string.Format("Load {0} red engine(s) on the truck destined for {1}",
                    totalQuantityShippingHold, Constants.Trucks_Destinations.RED_TRUCK));
                Console.WriteLine("");

                if (totalReturnToStock > 0)
                {
                    Console.WriteLine(string.Format("{0} of the {1} yellow engine(s) exceed load capacity. Please return them to stock", 
                        totalReturnToStock.ToString(), engine.QuantityShipping.ToString()));
                    Console.WriteLine("");
                }
            }
            else
            {
                successor.HandleRequest(engine);
            }

            return engine;
        }
    }
}

The final concrete handler in the successor chain handles the workload for yellow engines. If neither the blue concrete handler nor the yellow concrete handler are able to act upon the contents of the request message, then it’s likely that the yellow concrete handler will be responsible for the work. If not, then it too falls through the chain and returns the same IEngine values that were passed into it, meaning no work was performed on the request message.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using THE_TruckKing.Utilities;
using THE_TruckKing.Interfaces;

namespace THE_TruckKing
{
    /// <summary>
    /// Handles yellow engine shipments to Des Moines, IA
    /// </summary>
    /// 
    public class ShipmentHandlerYellow : Handler
    {
        public override IEngine HandleRequest(IEngine engine)
        {
            int totalQuantityShippingHold = 0;
            int totalReturnToStock = 0;

            if (engine.Type == Constants.Engines.YELLOW_ENGINE)
            {
                for (int i = 0; i < engine.QuantityShipping; i++)
                {
                    if (Constants.Engine_MAX_Weights.YELLOW_ENGINE >=
                        ((engine.TotalQuantityShipping + 1) * Constants.Engine_Base_Weights.YELLOW_ENGINE))
                    {
                        engine.TotalQuantityShipping += 1;
                        totalQuantityShippingHold += 1;
                    }
                    else
                    {
                        totalReturnToStock += 1;
                    }
                }

                Console.WriteLine(string.Format("Load {0} yellow engine(s) on the truck destined for {1}", 
                    totalQuantityShippingHold, Constants.Trucks_Destinations.YELLOW_TRUCK));
                Console.WriteLine("");

                if (totalReturnToStock > 0)
                {
                    Console.WriteLine(string.Format("{0} of the {1} yellow engine(s) exceed load capacity. Please return them to stock",
                        totalReturnToStock.ToString(), engine.QuantityShipping.ToString()));
                    Console.WriteLine("");
                }
            }
            else
            {
                successor.HandleRequest(engine);
            }

            return engine;
        }
    }
}


THE IEngine INTERFACE

You’ll notice that each concrete handler accepts the same IEngine interface type, which inherits from the same handler class. This is ultimately what allows the chain-of-responsibility pattern to work. IEngine also implies that we have a concrete class that abides by the tenants of the IEngine interface, so we’ll define the IEngine interface and the concrete Engine type, below:

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

namespace THE_TruckKing.Interfaces
{
    public interface IEngine
    {
        int ID { get; set; }
        string Name { get; set; }
        string Description { get; set; }
        string Type { get; set; }
        string ModelNumber { get; set; }
        int QuantityShipping { get; set; }
        int TotalQuantityShipping { get; set; }
        decimal EngineWeightShipping { get; set; }
        decimal TotalWeightShipped { get; set; }
        decimal BaseWeight { get; set; }
    }
}


THE ENGINE CLASS

The engine class is pretty straightforward. It implements the IEngine interface and provides us with a mechanism in which to store our payload data. Actually, I’m not very fond of including this in my example, because I believe that most of this can be inferred and it unnecessarily bloats the example. However, I’ve included it anyway just to be thorough.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using THE_TruckKing.Interfaces;
using System.Runtime.Serialization;

namespace THE_TruckKing.Entities
{
    [Serializable()]
    public class Engine : IEngine
    {
        private int _ID = 0;

        int IEngine.ID
        {
            get
            {
                return _ID;
            }
            set
            {
                _ID = value;
            }
        }

        private string _Name = string.Empty;

        string IEngine.Name
        {
            get
            {
                return _Name;
            }
            set
            {
                _Name = value;
            }
        }

        private string _Description = string.Empty;

        string IEngine.Description
        {
            get
            {
                return _Description;
            }
            set
            {
                _Description = value;
            }
        }

        private string _Type = string.Empty;

        string IEngine.Type
        {
            get
            {
                return _Type;
            }
            set
            {
                _Type = value;
            }
        }

        private string _ModelNumber = string.Empty;

        string IEngine.ModelNumber
        {
            get
            {
                return _ModelNumber;
            }
            set
            {
                _ModelNumber = value;
            }
        }

        private int _QuantityShipping = 0;

        int IEngine.QuantityShipping
        {
            get
            {
                return _QuantityShipping;
            }
            set
            {
                _QuantityShipping = value;
            }
        }

        private int _TotalQuantityShipping = 0;

        int IEngine.TotalQuantityShipping
        {
            get
            {
                return _TotalQuantityShipping;
            }
            set
            {
                _TotalQuantityShipping = value;
            }
        }

        private decimal _EngineWeightShipping = 0.0m;

        decimal IEngine.EngineWeightShipping
        {
            get
            {
                return _EngineWeightShipping;
            }
            set
            {
                _EngineWeightShipping = value;
            }
        }

        private decimal _TotalWeightShipped = 0.0m;

        decimal IEngine.TotalWeightShipped
        {
            get
            {
                return _TotalWeightShipped;
            }
            set
            {
                _TotalWeightShipped = value;
            }
        }

        private decimal _BaseWeight = 0.0m;

        decimal IEngine.BaseWeight
        {
            get
            {
                return _BaseWeight;
            }
            set
            {
                _BaseWeight = value;
            }
        }
    }
}


THE CONSTANT CLASSES

For purposes of simplicity, my solution doesn’t tie into a database, so I’m inferring all of my references by front loading the base IEngine types. In reality, you would be much better off storing these values in a data backing store of your choice (e.g. configuration, database, etc..).

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

namespace THE_TruckKing.Utilities
{
    public static class Constants
    {
        public static class Engines
        {
            public const string RED_ENGINE = "R1773456935";
            public const string BLUE_ENGINE = "B8439845841";
            public const string YELLOW_ENGINE = "Y4833345760";
        }

        public static class Engine_Base_Weights
        {
            public const decimal RED_ENGINE = 532;
            public const decimal BLUE_ENGINE = 1386;
            public const decimal YELLOW_ENGINE = 1783;
        }

        public static class Engine_MAX_Weights
        {
            public const decimal RED_ENGINE = 5000;
            public const decimal BLUE_ENGINE = 6500;
            public const decimal YELLOW_ENGINE = 6000;
        }

        public static class Trucks
        {
            public const string RED_TRUCK = "the red truck";
            public const string BLUE_TRUCK = "the blue truck";
            public const string YELLOW_TRUCK = "the yellow truck";
        }

        public static class Trucks_Destinations
        {
            public const string RED_TRUCK = "Chicago, IL";
            public const string BLUE_TRUCK = "Overland Park, KS";
            public const string YELLOW_TRUCK = "Des Moines, IA";
        }
    }
}


IoC THROUGH THE MICROSOFT UNITY FRAMEWORK

There is one more class that I’ll implement in the project, and that’s an Inversion of Control (IoC) pattern using the Microsoft Unity Framework. I’m using Microsoft Unity 3 in this example, which can be downloaded here:

Microsoft Unity Framework 3

Basically, you just download it, or the latest version of it, and unpack it in a directory on your machine. Afterwards, you’ll be able to reference different assemblies to exact the specific actions you desire by referencing different assemblies (e.g. MVC, Service Locator, Dependency Injection, etc…) in the Unity download. Of course, you’ll still have to hand roll any patterns not provided by the Unity Library, but it will still offer you with a decent jump start in the areas that the library does specifically address.

In this example, what I’m trying to achieve is this:

  • I want to decouple object dependencies from the main assembly to any client applications, which will allow me to minimize the amount of work necessary to replace or update certain properties to the IEngine and Engine classes without necessarily forcing me to make changes to methods that leverage these classes throughout the solution.
  • I’m assuming that the client application that will eventually consume this assembly will need to know very little about its concrete implementation at compile time, so adding or subtracting certain properties to the interface and its support concrete type should pose little or no rework for the client applications.
  • Even though I didn’t follow a TDD approach, I still might want to create unit tests that perform assertions on various parts of the code base in the future, so each class and method must be able to be tested against without using any dependencies.
  • I want to decouple my classes from being responsible for locating and managing the lifetime of dependencies.
    After installing the Microsoft Unity Framework, create references to the following assemblies within the project:
  • Microsoft.Practices.Unity.dll
  • Microsoft.Practices.Unity.Configuration.dll

Next, drop in the following factory pattern to setup the ability to create an instance of the Engine object. Ideally, our client application will simply be able to call the CreateInstance method and pass the desired engineType to Register and Resolve the IoC Container for the object, as well as set a few base properties. We’ll achieve this using the Microsoft Unity Framework.


THE IoC CONTAINER FACTORY

Before I focus too deeply on the following code, I want to point out that I’ve hardcoded the classes in order to simplify the readability of the code. Normally the classes would be driven through some form of dynamic configuration. Regardless…

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Entites = THE_TruckKing.Entities;
using THE_TruckKing.Interfaces;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using THE_TruckKing.Utilities;

namespace THE_TruckKing.Factories
{
    public class Engine
    {
        static public IEngine CreateInstance(string engineType)
        {
            IUnityContainer _container = new UnityContainer();
            _container.RegisterType(typeof(IEngine), typeof(Entities.Engine));
            IEngine obj = _container.Resolve<IEngine>();
            return obj;
        }

        static private IEngine SetValues(IEngine engine, string engineType)
        {
            try
            {
                switch (engineType)
                {
                    case Constants.Engines.RED_ENGINE:
                        {
                            engine.Type = Constants.Engines.RED_ENGINE;
                            engine.BaseWeight = Constants.Engine_Base_Weights.RED_ENGINE;
                            break;
                        }
                    case Constants.Engines.BLUE_ENGINE:
                        {
                            engine.Type = Constants.Engines.BLUE_ENGINE;
                            engine.BaseWeight = Constants.Engine_Base_Weights.BLUE_ENGINE;
                            break;
                        }
                    case Constants.Engines.YELLOW_ENGINE:
                        {
                            engine.Type = Constants.Engines.YELLOW_ENGINE;
                            engine.BaseWeight = Constants.Engine_Base_Weights.YELLOW_ENGINE;
                            break;
                        }
                    default:
                        {
                            break;
                        }
                }
                
                return engine;
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
}


CREATING THE CHAIN-OF-RESPONSIBILITY COMMANDS

At this point, we’ve coded a textbook Chain-of-Responsibility design pattern. But, in order to complete the pattern we still need to establish the successive order of the handlers in the chain. So, we’ll solve this piece of the puzzle by creating a quick console application that references both the assembly we just created, as well as a couple of the Microsoft Unity Framework assemblies:

  • Microsoft.Practices.Unity.dll
  • Microsoft.Practices.Unity.Configuration.dll

Afterwards, drop the following code in:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using THE_TruckKing;
using THE_TruckKing.Utilities;
using THE_TruckKing.Interfaces;
using THE_TruckKing.Entities;
using Factories = THE_TruckKing.Factories;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;


namespace CoR_Pattern_Client
{
    /// <summary>
    /// Program that signifies an engine is ready to be loaded at the dock
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            int x = 0;

            // Calls the Unity IoC Factory Handler to create the instances of the objects
            IEngine redEngine = Factories.Engine.CreateInstance(Constants.Engines.RED_ENGINE);
            IEngine blueEngine = Factories.Engine.CreateInstance(Constants.Engines.BLUE_ENGINE);
            IEngine yellowEngine = Factories.Engine.CreateInstance(Constants.Engines.YELLOW_ENGINE);

            while (x != 999)
            {
                Console.WriteLine("Specify an engine that is ready to be loaded:");
                Console.WriteLine("");
                Console.WriteLine("Press (R) - To Load Red Engine");
                Console.WriteLine("Press (Y) - To Load Yellow Engine");
                Console.WriteLine("Press (B) - To Load Blue Engine");
                Console.WriteLine("Press (Q) - To Quit");

                var input = Console.ReadKey();
                Console.WriteLine("");
                Console.WriteLine("");

                // Completes the Chain-of-Responsibility Pattern
                Handler h1 = new ShipmentHandlerBlue();
                Handler h2 = new ShipmentHandlerYellow();
                Handler h3 = new ShipmentHandlerRed();

                h1.SetSuccessor(h2);
                h2.SetSuccessor(h3);

                switch (input.Key.ToString().ToUpperInvariant())
                {
                    case "R":
                        {
                            redEngine.Type = Constants.Engines.RED_ENGINE;
                            redEngine.QuantityShipping = GetShipmentQuantity();
                            redEngine = h1.HandleRequest(redEngine);
                            break;
                        }
                    case "Y":
                        {
                            yellowEngine.Type = Constants.Engines.YELLOW_ENGINE;
                            yellowEngine.QuantityShipping = GetShipmentQuantity();
                            yellowEngine = h1.HandleRequest(yellowEngine);
                            break;
                        }
                    case "B":
                        {
                            blueEngine.Type = Constants.Engines.BLUE_ENGINE;
                            blueEngine.QuantityShipping = GetShipmentQuantity();
                            blueEngine = h1.HandleRequest(blueEngine);                            
                            break;
                        }
                    case "Q":
                        {
                            Environment.Exit(0);
                            break;
                        }
                    default:
                        {
                            break;
                        }
                }

                Console.ReadLine();
                Console.Clear();
            }
        }

        private static int GetShipmentQuantity()
        {
            int quantity = 0;

            try
            {
                Console.WriteLine("");
                Console.WriteLine("How many engines are you loading?");
                quantity = int.Parse(Console.ReadLine());
                Console.WriteLine("");
                return quantity;
            }
            catch (Exception)
            {
                return 0;
            }
        }
    }
}


FINALLY

Take special note of the following lines of code that exist in the previous codebase. First, we’ll focus on the Microsoft Unity, Inversion of Control aspect of it, which is exhibited in the following lines of code:

  • IEngine redEngine = Factories.Engine.CreateInstance();
  • IEngine blueEngine = Factories.Engine.CreateInstance();
  • IEngine yellowEngine = Factories.Engine.CreateInstance();

This is what allows us to decouple our object dependencies from the main assembly to any client applications. The control of each object’s creation is inverted to the Factory inside the assembly, so the client needs to know very little about creating or consuming the object itself. The Microsoft Unity Framework takes care of all of this for you.

The next interesting piece involves closing the gap on the chain-of-responsibility pattern by implementing a definitive successor chain of responsibilities using the concrete handler types. The following lines of code designate that the ShipmentHandlerBlue() concrete handler will receive the initial payload request, and if it can’t handle it then it then it will be its responsibility to pass the request message along to the ShipmentHanlderYellow() concrete handler in the chain.

Finally, if it can’t handle the payload request, then it will finally pass the responsibility down the chain to the ShipmentHandlerRead concrete handler for fulfillment. Each concrete handler acts autonomously in the chain, meaning that it doesn’t have to know anything else about any other concrete handler, enacting a true separation of concerns and a classic, textbook example of the chain-of-responsibility pattern itself.

Handler h1 = new ShipmentHandlerBlue();
Handler h2 = new ShipmentHandlerYellow();
Handler h3 = new ShipmentHandlerRed();

h1.SetSuccessor(h2);
h2.SetSuccessor(h3);

When you run the application, you should see the following results:

Image1

Image2

Image3

Thanks for reading and keep on coding! 🙂