責任鏈模式

1. 加薪代碼初步

B: 管理類裏面的結構方法比較長,加上有太多的分支判斷,這其實很是很差的設計。
A: 很好,由於你很難講當中會不會增長其餘的管理類別,好比項目經理,部門經理等等。這個類承擔了太多的責任。
B: 類有太多的責任,這違背了單一職責原則,增長新的類,須要修改這個類,違背了開放-封閉原則。
A: 如何解決經理無權上報總監這樣的功能?
B: 它們之間有必定的關聯,把用戶的請求傳遞,直到能夠解決這個請求爲止。dom

2. 責任鏈模式

是多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合。將這個對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它爲止。

A: 請求的客戶端並不知道這當中的哪一個對象最終處理這個請求,這樣系統的更改能夠在不影響客服端的狀況下動態地從新組織和分配責任。
圖1ide

class Program
{
    static void Main(string[] args)
    {
        Handler h1 = new ConcreteHandler1();
        Handler h2 = new ConcreteHandler2();
        Handler h3 = new ConcreteHandler3();
        h1.SetSuccessor(h2);
        h2.SetSuccessor(h3);

        int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 };

        foreach (int request in requests)
        {
            h1.HandleRequest(request);
        }

        Console.Read();

    }
}

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);
        }
    }
}

3. 責任鏈的好處

A: 這當中最關鍵的是當客戶提交一個請求是,請求是沿着鏈傳遞直至有一個ConcreteHandler對象負責處理它。
A: 這就使得接收者和發送者都沒有對方的明確信息,且鏈中的對象本身也並不知道鏈的結構。結構是職責鏈可簡化對象的互相鏈接,它們僅需保持一個指向其後繼者的引用,而不需保持它全部的候選接受者的引用。
B: 隨時地增長或修改一個請求的結構。加強了給對象指派職責的靈活性。
A: 不過也要小心,一個請求極有可能到了鏈的末端都得不處處理,或者由於沒有正確配置而得不處處理,這很糟糕。this

4. 加薪代碼重構

圖2
注意客戶端是如何編寫的:spa

class Program
{
    static void Main(string[] args)
    {

        CommonManager jinli = new CommonManager("金利");
        Majordomo zongjian = new Majordomo("宗劍");
        GeneralManager zhongjingli = new GeneralManager("鍾精勵");
        jinli.SetSuperior(zongjian);
        zongjian.SetSuperior(zhongjingli);

        Request request = new Request();
        request.RequestType = "請假";
        request.RequestContent = "小菜請假";
        request.Number = 1;
        jinli.RequestApplications(request);

        Request request2 = new Request();
        request2.RequestType = "請假";
        request2.RequestContent = "小菜請假";
        request2.Number = 4;
        jinli.RequestApplications(request2);

        Request request3 = new Request();
        request3.RequestType = "加薪";
        request3.RequestContent = "小菜請求加薪";
        request3.Number = 500;
        jinli.RequestApplications(request3);

        Request request4 = new Request();
        request4.RequestType = "加薪";
        request4.RequestContent = "小菜請求加薪";
        request4.Number = 1000;
        jinli.RequestApplications(request4);

        Console.Read();

    }
}

//管理者
abstract class Manager
{
    protected string name;
    //管理者的上級
    protected Manager superior;

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

    //設置管理者的上級
    public void SetSuperior(Manager superior)
    {
        this.superior = superior;
    }

    //申請請求
    abstract public void RequestApplications(Request request);
}

//經理
class CommonManager : Manager
{
    public CommonManager(string name)
        : base(name)
    { }
    public override void RequestApplications(Request request)
    {

        if (request.RequestType == "請假" && request.Number <= 2)
        {
            Console.WriteLine("{0}:{1} 數量{2} 被批准", name, request.RequestContent, request.Number);
        }
        else
        {
            if (superior != null)
                superior.RequestApplications(request);
        }

    }
}

//總監
class Majordomo : Manager
{
    public Majordomo(string name)
        : base(name)
    { }
    public override void RequestApplications(Request request)
    {

        if (request.RequestType == "請假" && request.Number <= 5)
        {
            Console.WriteLine("{0}:{1} 數量{2} 被批准", 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 == "請假")
        {
            Console.WriteLine("{0}:{1} 數量{2} 被批准", name, request.RequestContent, request.Number);
        }
        else if (request.RequestType == "加薪" && request.Number <= 500)
        {
            Console.WriteLine("{0}:{1} 數量{2} 被批准", name, request.RequestContent, request.Number);
        }
        else if (request.RequestType == "加薪" && request.Number > 500)
        {
            Console.WriteLine("{0}:{1} 數量{2} 再說吧", name, request.RequestContent, request.Number);
        }
    }
}

//申請
class Request
{
    //申請類別
    private string requestType;
    public string RequestType
    {
        get { return requestType; }
        set { requestType = value; }
    }

    //申請內容
    private string requestContent;
    public string RequestContent
    {
        get { return requestContent; }
        set { requestContent = value; }
    }

    //數量
    private int number;
    public int Number
    {
        get { return number; }
        set { number = value; }
    }
}

這很好解決了原來的大量分支判斷形成難維護,靈活性差的問題。設計

相關文章
相關標籤/搜索