設計模式(19)---職責鏈模式

1、定義dom

職責鏈模式:使得多個對象都有機會處理請求,從而避免請求的發送者和接受者之間的耦合關係。將這個對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它爲止。ide

解釋:簡單來講應該是對於一個請求,不一樣的人根據本身職責範圍對它進行處理,同時也由於它通常是從底層向上層傳遞的請求的,因此將處理該請求的不一樣的對象比喻成一個鏈,從相對「低」的地方傳遞到相對「高」的地方,從而完成請求操做。性能

 

2、UML類圖及基本代碼this

基本代碼:spa

abstract class Handler
    {
        protected Handler successor;

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

        public abstract void HandleRequest(int request);
    }

    class ConcreteHandler1 : Handler
    {
        public override void HandleRequest(int request)
        {
            if (request >= 0 && request < 10)
            {
                Console.WriteLine("{0}處理請求{1}", this.GetType().Name, request);
            }
            else if (successor != null)
            {
                successor.HandleRequest(request);
            }
        }
    }

    class ConcreteHandler2 : Handler
    {
        public override void HandleRequest(int request)
        {
            if (request >= 10 && request < 20)
            {
                Console.WriteLine("{0}處理請求{1}", this.GetType().Name, request);
            }
            else if (successor != null)
            {
                successor.HandleRequest(request);
            }
        }
    }

    class ConcreteHandler3 : Handler
    {
        public override void HandleRequest(int request)
        {
            if (request >= 20 && request < 30)
            {
                Console.WriteLine("{0}處理請求{1}", this.GetType().Name, request);
            }
            else if (successor != null)
            {
                successor.HandleRequest(request);
            }
        }
    }

 

客戶端調用及其結果:3d

Handler h1 = new ConcreteHandler1();
            Handler h2 = new ConcreteHandler2();
            Handler h3 = new ConcreteHandler3();
            h1.SetSuccessor(h2);
            h2.SetSuccessor(h3);

            int[] requests = { 6, 5, 14, 23, 18, 9, 17, 6, 26 };
            foreach (int request in requests)
            {
                h1.HandleRequest(request);
            }
View Code

 

3、具體實例code

列舉一個能更加說明職責鏈的實例。john在單位,向領導請假,小於等於2天經理有權利批准,小於等於5天總監有權利批准,其餘的則要交到總經理那裏批准。具體代碼以下:對象

class Request
    {
        public string RequestType{get;set;}
        public string RequestContent{get;set;}
        public int Number{get;set;}
    }

    abstract class Manager
    {
        protected string name;
        protected Manager superior;

        public Manager(string name)
        {
            this.name = name;
        }

        public void SetSuperior(Manager superior)
        {
            this.superior = superior;
        }

        public abstract void RequestApplications(Request request);
    }

    class CommonManager : Manager
    {
        public CommonManager(string name)
            : base(name)
        { }

        public override void RequestApplications(Request request)
        {
            if (request.RequestType == "leave" && request.Number <= 2)
            {
                Console.WriteLine("{0}:{1} number is {2} ok", name, request.RequestContent, request.Number);
            }
            else
            {
                if (superior != null)
                {
                    superior.RequestApplications(request);
                }
            }
        }
    }

    class Majordome : Manager
    {
        public Majordome(string name)
            : base(name)
        { }

        public override void RequestApplications(Request request)
        {
            if (request.RequestType == "leave" && request.Number <= 5)
            {
                Console.WriteLine("{0}:{1} number is {2} ok", name, request.RequestContent, request.Number);
            }
            else
            {
                if (superior != null)
                {
                    superior.RequestApplications(request);
                }
            }
        }
    }

    class GeneralManager : Manager
    {
        public GeneralManager(string name)
            : base(name)
        { }

        public override void RequestApplications(Request request)
        {
            if (request.RequestType == "leave")
            {
                Console.WriteLine("{0}:{1} number is {2} ok", name, request.RequestContent, request.Number);
            }
            else if (request.RequestType == "add money" && request.Number <= 500)
            {
                Console.WriteLine("{0}:{1} number is {2} ok", name, request.RequestContent, request.Number);
            }
            else if (request.RequestType == "add money" && request.Number > 500)
            {
                Console.WriteLine("{0}:{1} number is {2} not ok", name, request.RequestContent, request.Number);
            }
        }
    }
View Code

 

客戶端調用及結果:blog

CommonManager jinli = new CommonManager("經理");
            Majordome zongjian = new Majordome("總監");
            GeneralManager zhongjingli = new GeneralManager("總經理");
            jinli.SetSuperior(zongjian);
            zongjian.SetSuperior(zhongjingli);

            Request request = new Request();
            request.RequestType = "leave";
            request.RequestContent = "john ask for days";
            request.Number = 2;
            jinli.RequestApplications(request);

            Request request2 = new Request();
            request2.RequestType = "leave";
            request2.RequestContent = "john ask for days";
            request2.Number = 5;
            jinli.RequestApplications(request2);
View Code

 

4、優缺點及適用場景get

優勢:

1)下降了請求發送者和處理者之間的耦合。

2)把多個條件斷定分散到各個處理類中,使得代碼更加清晰,責任更加明確。

缺點:

1)在找到正確的處理對象以前,全部的條件斷定都要執行一遍,當職責鏈過長時,可能會引發性能問題。

2)可能致使某個請求不被處理。

 

適用場景:

1)一個系統的請求須要多個對象進行審批才能完成的狀況。

2)代碼中有多個if-else時,也能夠考慮使用職責鏈模式對代碼進行重構。

相關文章
相關標籤/搜索