<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          C#設(shè)計(jì)模式—責(zé)任鏈模式

          共 4785字,需瀏覽 10分鐘

           ·

          2022-01-04 10:35

          一、引言

            在現(xiàn)實(shí)生活中,有很多請(qǐng)求并不是一個(gè)人說(shuō)了就算的,例如面試時(shí)的工資,低于1萬(wàn)的薪水可能技術(shù)經(jīng)理就可以決定了,但是1萬(wàn)~1萬(wàn)5的薪水可能技術(shù)經(jīng)理就沒(méi)這個(gè)權(quán)利批準(zhǔn),可能就需要請(qǐng)求技術(shù)總監(jiān)的批準(zhǔn),所以在面試的完后,經(jīng)常會(huì)有面試官說(shuō),你這個(gè)薪水我這邊覺(jué)得你這技術(shù)可以拿這個(gè)薪水的,但是還需要技術(shù)總監(jiān)的批準(zhǔn)等的話(huà)。這個(gè)例子也就詮釋了本文要介紹的內(nèi)容。生活中的這個(gè)例子真是應(yīng)用了責(zé)任鏈模式。

          二、責(zé)任鏈模式介紹

          2.1 責(zé)任鏈模式的定義

            從生活中的例子可以發(fā)現(xiàn),某個(gè)請(qǐng)求可能需要幾個(gè)人的審批,即使技術(shù)經(jīng)理審批完了,還需要上一級(jí)的審批。這樣的例子,還有公司中的請(qǐng)假,少于3天的,直屬Leader就可以批準(zhǔn),3天到7天之內(nèi)就需要項(xiàng)目經(jīng)理批準(zhǔn),多余7天的就需要技術(shù)總監(jiān)的批準(zhǔn)了。介紹了這么多生活中責(zé)任鏈模式的例子的,下面具體給出面向?qū)ο笾胸?zé)任鏈模式的定義。

            責(zé)任鏈模式指的是——某個(gè)請(qǐng)求需要多個(gè)對(duì)象進(jìn)行處理,從而避免請(qǐng)求的發(fā)送者和接收之間的耦合關(guān)系。將這些對(duì)象連成一條鏈子,并沿著這條鏈子傳遞該請(qǐng)求,直到有對(duì)象處理它為止。

          2.2 責(zé)任鏈模式的結(jié)構(gòu)圖

            從責(zé)任鏈模式的定義可以發(fā)現(xiàn),責(zé)任鏈模式涉及的對(duì)象只有處理者角色,但由于有多個(gè)處理者,它們具有共同的處理請(qǐng)求的方法,所以這里抽象出一個(gè)抽象處理者角色進(jìn)行代碼復(fù)用。這樣分析下來(lái),責(zé)任鏈模式的結(jié)構(gòu)圖也就不言而喻了,具體結(jié)構(gòu)圖如下所示。

            主要涉及兩個(gè)角色:

          ·?抽象處理者角色(Handler):定義出一個(gè)處理請(qǐng)求的接口。這個(gè)接口通常由接口或抽象類(lèi)來(lái)實(shí)現(xiàn)。

          ·?具體處理者角色(ConcreteHandler):具體處理者接受到請(qǐng)求后,可以選擇將該請(qǐng)求處理掉,或者將請(qǐng)求傳給下一個(gè)處理者。因此,每個(gè)具體處理者需要保存下一個(gè)處理者的引用,以便把請(qǐng)求傳遞下去。

          2.3 責(zé)任鏈模式的實(shí)現(xiàn)

            有了上面的介紹,下面以公司采購(gòu)東西為例子來(lái)實(shí)現(xiàn)責(zé)任鏈模式。公司規(guī)定,采購(gòu)架構(gòu)總價(jià)在1萬(wàn)之內(nèi),經(jīng)理級(jí)別的人批準(zhǔn)即可,總價(jià)大于1萬(wàn)小于2萬(wàn)5的則還需要副總進(jìn)行批準(zhǔn),總價(jià)大于2萬(wàn)5小于10萬(wàn)的需要還需要總經(jīng)理批準(zhǔn),而大于總價(jià)大于10萬(wàn)的則需要組織一個(gè)會(huì)議進(jìn)行討論。對(duì)于這樣一個(gè)需求,最直觀的方法就是設(shè)計(jì)一個(gè)方法,參數(shù)是采購(gòu)的總價(jià),然后在這個(gè)方法內(nèi)對(duì)價(jià)格進(jìn)行調(diào)整判斷,然后針對(duì)不同的條件交給不同級(jí)別的人去處理,這樣確實(shí)可以解決問(wèn)題,但這樣一來(lái),我們就需要多重if-else語(yǔ)句來(lái)進(jìn)行判斷,但當(dāng)加入一個(gè)新的條件范圍時(shí),我們又不得不去修改原來(lái)設(shè)計(jì)的方法來(lái)再添加一個(gè)條件判斷,這樣的設(shè)計(jì)顯然違背了開(kāi)-原則。這時(shí)候,可以采用責(zé)任鏈模式來(lái)解決這樣的問(wèn)題。具體實(shí)現(xiàn)代碼如下所示。

          ?

          namespace?ChainofResponsibility

          {

          ????// 采購(gòu)請(qǐng)求

          ????public?class?PurchaseRequest

          ????{

          ????????// 金額

          ????????public?double?Amount { get; set; }

          ????????// 產(chǎn)品名字

          ????????public?string?ProductName { get; set; }

          ????????public?PurchaseRequest(double?amount, string?productName)

          ????????{

          ????????????Amount = amount;

          ????????????ProductName = productName;

          ????????}

          ????}

          ?

          ????// 審批人,Handler

          ????public?abstract?class?Approver

          ????{

          ????????public?Approver NextApprover { get; set; }

          ????????public?string?Name { get; set; }

          ????????public?Approver(string?name)

          ????????{

          ????????????this.Name = name;

          ????????}

          ????????public?abstract?void?ProcessRequest(PurchaseRequest request);

          ????}

          ?

          ????// ConcreteHandler

          ????public?class?Manager : Approver

          ????{

          ????????public?Manager(string?name)

          ????????????: base(name)

          ????????{ }

          ?

          ????????public?override?void?ProcessRequest(PurchaseRequest request)

          ????????{

          ????????????if?(request.Amount < 10000.0)

          ????????????{

          ????????????????Console.WriteLine("{0}-{1} approved the request of purshing {2}", this, Name, request.ProductName);

          ????????????}

          ????????????else?if?(NextApprover != null)

          ????????????{

          ????????????????NextApprover.ProcessRequest(request);

          ????????????}

          ????????}

          ????}

          ?

          ????// ConcreteHandler,副總

          ????public?class?VicePresident : Approver

          ????{

          ????????public?VicePresident(string?name)

          ????????????: base(name)

          ????????{

          ????????}

          ????????public?override?void?ProcessRequest(PurchaseRequest request)

          ????????{

          ????????????if?(request.Amount < 25000.0)

          ????????????{

          ????????????????Console.WriteLine("{0}-{1} approved the request of purshing {2}", this, Name, request.ProductName);

          ????????????}

          ????????????else?if?(NextApprover != null)

          ????????????{

          ????????????????NextApprover.ProcessRequest(request);

          ????????????}

          ????????}

          ????}

          ?

          ????// ConcreteHandler,總經(jīng)理

          ????public?class?President :Approver

          ????{

          ????????public?President(string?name)

          ????????????: base(name)

          ????????{ }

          ????????public?override?void?ProcessRequest(PurchaseRequest request)

          ????????{

          ????????????if?(request.Amount < 100000.0)

          ????????????{

          ????????????????Console.WriteLine("{0}-{1} approved the request of purshing {2}", this, Name, request.ProductName);

          ????????????}

          ????????????else

          ????????????{

          ????????????????Console.WriteLine("Request需要組織一個(gè)會(huì)議討論");

          ????????????}

          ????????}

          ????}

          ?

          ????class?Program

          ????{

          ????????static?void?Main(string[] args)

          ????????{

          ????????????PurchaseRequest requestTelphone = new?PurchaseRequest(4000.0, "Telphone");

          ????????????PurchaseRequest requestSoftware = new?PurchaseRequest(10000.0, "Visual Studio");

          ????????????PurchaseRequest requestComputers = new?PurchaseRequest(40000.0, "Computers");

          ?

          ????????????Approver manager = new?Manager("LearningHard");

          ????????????Approver Vp = new?VicePresident("Tony");

          ????????????Approver Pre = new?President("BossTom");

          ?

          ????????????// 設(shè)置責(zé)任鏈

          ????????????manager.NextApprover = Vp;

          ????????????Vp.NextApprover = Pre;

          ?

          ????????????// 處理請(qǐng)求????????????

          ? ? ? ? ? ? manager.ProcessRequest(requestTelphone);

          ????????????manager.ProcessRequest(requestSoftware);

          ????????????manager.ProcessRequest(requestComputers);

          ????????????Console.ReadLine();

          ????????}

          ????}

          }


            既然,原來(lái)的設(shè)計(jì)會(huì)因?yàn)閮r(jià)格條件范圍的變化而導(dǎo)致不利于擴(kuò)展,根據(jù)封裝變化的原則,此時(shí)我們想的自然是能不能把價(jià)格范圍細(xì)化到不同的類(lèi)中呢?因?yàn)槊總€(gè)價(jià)格范圍都決定某個(gè)批準(zhǔn)者,這里就聯(lián)想到創(chuàng)建多個(gè)批準(zhǔn)類(lèi),這樣每個(gè)類(lèi)中只需要針對(duì)他自己這個(gè)范圍的價(jià)格判斷。這樣也就是責(zé)任鏈的最后實(shí)現(xiàn)方式了,具體的運(yùn)行結(jié)果如下圖所示。

          三、責(zé)任鏈模式的適用場(chǎng)景?

            在以下場(chǎng)景中可以考慮使用責(zé)任鏈模式:

          ·?一個(gè)系統(tǒng)的審批需要多個(gè)對(duì)象才能完成處理的情況下,例如請(qǐng)假系統(tǒng)等。

          ·?代碼中存在多個(gè)if-else語(yǔ)句的情況下,此時(shí)可以考慮使用責(zé)任鏈模式來(lái)對(duì)代碼進(jìn)行重構(gòu)。

          四、責(zé)任鏈模式的優(yōu)缺點(diǎn)

            責(zé)任鏈模式的優(yōu)點(diǎn)不言而喻,主要有以下點(diǎn):

          ·?降低了請(qǐng)求的發(fā)送者和接收者之間的耦合。

          ·?把多個(gè)條件判定分散到各個(gè)處理類(lèi)中,使得代碼更加清晰,責(zé)任更加明確。

            責(zé)任鏈模式也具有一定的缺點(diǎn),如:

          ·?在找到正確的處理對(duì)象之前,所有的條件判定都要執(zhí)行一遍,當(dāng)責(zé)任鏈過(guò)長(zhǎng)時(shí),可能會(huì)引起性能的問(wèn)題

          ·?可能導(dǎo)致某個(gè)請(qǐng)求不被處理。

          五、總結(jié)

            責(zé)任鏈降低了請(qǐng)求端和接收端之間的耦合,使多個(gè)對(duì)象都有機(jī)會(huì)處理某個(gè)請(qǐng)求。如考試中作弊傳紙條,泡妞傳情書(shū)一般。?




          瀏覽 20
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  A片视频免费看 | 男女黄A片 | 免费无码毛片 | 国产精品国产精品国产 | 成人电影无码三区 |