`
chenying998179
  • 浏览: 25232 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Chain of Responsibility Pattern Example in C#

阅读更多

The Chain of Responsibility pattern takes a request and flows through a chain of handlers. Each handler checks if it can handle the request according to some business rules. If the handler can’t handle the request it gets passed to the next handler in the chain. The client doesn’t know which handler eventually handles the request.

In this example we send a parcel with a certain value. Some of the packages are insured. Based on the following criteria a package gets a certain treatment. For uninsured parcels with a value lower than 50 there is the budget treatment (you don’t want that). Parcels with a uninsured value from 50 and up get a normal treatment. All insured packages get a treatment deluxe. The chain of handlers is set up in that order.

Chain Of Responsibility Diagram

The base handler takes care of registering the next handler in the chain. A concreet implementation of a handler is show below. The ParcelHandlerBudget is the first in the chain of responsibility and checks if it can handle the parcel in the Handle() method. If so, we return a message with some hints to the kind of treatment the parcel is getting. If not, the NextHandler’s Handle() method is called.

namespace ChainOfResponsibilityPattern
{
    public class ParcelHandlerBudget : ParcelHandlerBase
    {
        public override string Handle(Parcel parcel)
        {
            if (parcel.Value < 50m && !parcel.IsInsured)
            {
                return "BUDGET: " +
                       "Assault package at a discount price";
            }

            return NextHandler.Handle(parcel);
        }
    }
}

In the client we create a parcel list with different (un)insured values and instantiate and chain up the parcel handlers. For every package on the list we walk up the chain of responsibility by calling Handle() on the first handler. The output of the ‘winning’ handler is returned and written to the console.

using System;
using System.Collections.Generic;

namespace ChainOfResponsibilityPattern
{
    internal class Program
    {
        private static void Main()
        {
            var parcelList =
                new List<Parcel>
                    {
                        new Parcel {IsInsured = false, Value = 2500m},
                        new Parcel {IsInsured = true, Value = 10m},
                        new Parcel {IsInsured = false, Value = 10m},
                        new Parcel {IsInsured = true, Value = 0m},
                        new Parcel {IsInsured = false, Value = 45m},
                        new Parcel {IsInsured = false, Value = 5m},
                        new Parcel {IsInsured = false, Value = 150m},
                    };

            var budgetHandler = new ParcelHandlerBudget();
            var normalHandler = new ParcelHandlerNormal();
            var deluxeHandler = new ParcelHandlerDeluxe();

            budgetHandler.SetNewHandler(normalHandler);
            normalHandler.SetNewHandler(deluxeHandler);

            foreach (Parcel parcel in parcelList)
            {
                try
                {
                    string result = budgetHandler.Handle(parcel);
                    Console.WriteLine(result);
                }
                catch (Exception)
                {
                    Console.WriteLine("Parcel rejected");
                }
            }

            Console.ReadKey();
        }
    }
}

Chain Of Responsibility Console

This design makes it easy to extend, change and maintain serial chain of responsibility rules. Further and recommended readings on the subject by Anoop Madhusudanan and Kory Becker.

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics