国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

淺談25種設計模式(4/25)(此坑未填)

0xE7A38A / 2810人閱讀

摘要:適配器模式橋接模式過濾器模式組合模式裝飾器模式外觀模式享元模式代理模式行為型模式這些設計模式特別關(guān)注對象之間的通信。對象適配器另外一種適配器模式是對象適配器,它不是使用多繼承或繼承再實現(xiàn)的方式,而是使用直接關(guān)聯(lián),或者稱為委托的方式。

設計模式匯總 創(chuàng)建型模式

這些設計模式提供了一種在創(chuàng)建對象的同時隱藏創(chuàng)建邏輯的方式,而不是使用新的運算符直接實例化對象。這使得程序在判斷針對某個給定實例需要創(chuàng)建哪些對象時更加靈活。

工廠模式(Factory Pattern)

抽象工廠模式(Abstract Factory Pattern)

單例模式(Singleton Pattern)

建造者模式(Builder Pattern)

原型模式(Prototype Pattern)

結(jié)構(gòu)型模式

這些設計模式關(guān)注類和對象的組合。繼承的概念被用來組合接口和定義組合對象獲得新功能的方式。

適配器模式(Adapter Pattern)

橋接模式(Bridge Pattern)

過濾器模式(Filter、Criteria Pattern)

組合模式(Composite Pattern)

裝飾器模式(Decorator Pattern)

外觀模式(Facade Pattern)

享元模式(Flyweight Pattern)

代理模式(Proxy Pattern)

行為型模式

這些設計模式特別關(guān)注對象之間的通信。

責任鏈模式(Chain of Responsibility Pattern)

命令模式(Command Pattern)

解釋器模式(Interpreter Pattern)

迭代器模式(Iterator Pattern)

中介者模式(Mediator Pattern)

備忘錄模式(Memento Pattern)

觀察者模式(Observer Pattern)

狀態(tài)模式(State Pattern)

空對象模式(Null Object Pattern)

策略模式(Strategy Pattern)

模板模式(Template Pattern)

訪問者模式(Visitor Pattern)

1 適配器模式 定義

將一個類的接口轉(zhuǎn)換成客戶希望的另外一個接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些類可以在一起工作。
我們用圖來形象的解釋這一概念:

這里的重點在于,老接口有特殊功能,我們不忍舍棄,比如只有歐洲的插頭(老接口)能從插座里獲得電,沒有電我們過不下去。這個功能我們無法舍棄
為了繼續(xù)享受這個特殊功能,我們使用適配器模式,讓我們手中的美國的插頭(新接口),擁有老接口的能力。

本例使用場景

例如一個美國人說英語,一個中國人說中文,為了跟美國人做生意,說英文這個功能我們無法舍棄,但是我們是中國人,天生不會說英文。于是兩者想要交流,就需要一個適配器,來充當溝通兩者的工作。現(xiàn)在,我們希望讓一個能說中國話的個體(實現(xiàn)說中文的接口的類),開口說英文。

角色

目標接口(Target)(中文溝通能力的接口):定義了我們希望用來承載被適配類特殊功能的方法的接口,比如例子中,我們希望用中國人的說話方法,承載美國人的speak功能,說話方法就定義在該接口中。

目標類(Target class)(中國人類):我們所期待的擁有特殊功能的具體類,也就是要說英文的類。

需要適配的類(Adaptee)(美國人類):需要適配的類或適配者類,類中還有我們還不忍舍棄的功能,我們需要迂回實現(xiàn)他

適配器(Adapter)(翻譯類):通過包裝一個需要適配的對象,把原接口轉(zhuǎn)換成目標接口。

類適配器

適配器有兩種主要的實現(xiàn),我們先看第一種——類適配器

具體實現(xiàn)
// 被適配類,已存在的、具有還有用處的特殊功能、但不符合我們既有的標準接口的類 
//——本例中即為一個會說f**k的美國人(你可以看作這個美國人實現(xiàn)了說英文的接口,不過這個無關(guān)緊要,省略),他說的話我們聽不懂
class American{  
    public void speak() {  
        System.out.println("f**k");  
    }  
}  
// 目標接口,或稱為標準接口  ——這里是一個說中文能力的接口,他定義了方法“說話”。
interface SpeakChinese {  
    public void shuoHua();  
} 
// 具體目標類,只提供普通功能 ——這里我們的具體實現(xiàn)是一個中國人類,他實現(xiàn)了說中國話的接口
class Chinese implements SpeakChinese {  
    public void shuoHua() {  
        System.out.println("敲里嗎");  
    }  
}  
// 適配器類,繼承了被適配類,同時實現(xiàn)標準接口  ——現(xiàn)在我們覺得,那個美國人說的四字真言好拽哦,我也要學會,于是我們定義了適配器
class Adapter extends American implements SpeakChinese {  
    public void shuoHua() {  
        super.speak();  
    }  
}  
測試

現(xiàn)在我們定義一個laoWang,老王是一個Chinese,他會說話這個方法。
然后再定義一個適配器,看看適配器能不能用中文的說話方法,說出英文來。

// 測試類public class Client {  
    public static void main(String[] args) {  
        // 使用普通功能類  
        SpeakChinese laoWang= new Chinese();  
        laoWang.shuoHua();  
          
        // 使用特殊功能類,即適配類  
        SpeakChinese adapter = new Adapter();  
        adapter.shuoHua();  
    }  
}  

測試結(jié)果:

敲里嗎
f**k

很棒,現(xiàn)在用了適配器,適配器用說中文的方式,說出了這句著名的英文,現(xiàn)在我們迂回得到了說這四個字母的能力,可以去找外國友人交流感情了。

對象適配器

另外一種適配器模式是對象適配器,它不是使用多繼承或繼承再實現(xiàn)的方式,而是使用直接關(guān)聯(lián),或者稱為委托的方式。

具體實現(xiàn)

其他目標類和被適配類都一樣,就是適配器類的定義方式有所不同:

// 適配器類,直接關(guān)聯(lián)被適配類,同時實現(xiàn)標準接口  
class Adapter implements SpeakChinese {  
    // 直接關(guān)聯(lián)被適配類  
    private American american;  
      
    // 可以通過構(gòu)造函數(shù)傳入具體需要適配的被適配類對象  
    public Adapter (American american) {  
        this.american = american;  
    }  
      
    public void shuoHua() {  
        // 這里是使用委托的方式完成特殊功能  
        this.american.speak();  
    }  
}  
測試

在這里,我們?yōu)榱烁`活一點,定義了一個加州人,加州人和外面那些妖艷賤貨不一樣,他們比較優(yōu)雅,一般喜歡說hello。

class Californian extends American{  
    public void speak() {  
        System.out.println("hello");  
    }  
} 
public class Client {  
    public static void main(String[] args) {  
        // 使用普通功能類  
        SpeakChinese laoWang = new Chinese();  
        laoWang.shuoHua();  
          
        // 使用特殊功能類,即適配類,  
        // 需要先創(chuàng)建一個被適配類的對象作為參數(shù)  
        American tom = new Californian(){}
        Target adapter = new Adapter(tom);  
        adapter.shuoHua();  
    }  
}  

測試結(jié)果

敲里嗎
hello

同樣的,我們用適配器獲得了像加州人那樣優(yōu)雅的說英文的能力。對象適配器相對于類適配器來說比較靈活,我們可以復用這個適配器,通過傳參的不同,得到德克薩斯人,弗吉尼亞人,佛羅里達人的說話方式。

優(yōu)劣

模式總結(jié)

優(yōu)點

通過適配器,客戶端可以調(diào)用同一接口,因而對客戶端來說是透明的。這樣做更簡單、更直接、更緊湊。

復用了現(xiàn)存的類,解決了現(xiàn)存類和復用環(huán)境要求不一致的問題。

將目標類和適配者類解耦,通過引入一個適配器類重用現(xiàn)有的適配者類,而無需修改原有代碼。

一個對象適配器可以把多個不同的適配者類適配到同一個目標,也就是說,同一個適配器可以把適配者類和它的子類都適配到目標接口。

缺點

過多的使用適配器,會讓系統(tǒng)非常零亂,不易整體進行把握。比如,明明看到調(diào)用的是 A 接口,其實內(nèi)部被適配成了 B 接口的實現(xiàn),一個系統(tǒng)如果太多出現(xiàn)這種情況,無異于一場災難。因此如果不是很有必要,可以不使用適配器,而是直接對系統(tǒng)進行重構(gòu)。

2 策略模式 定義

首先我們理解策略的概念,策略就是一組算法,一種實現(xiàn)。策略模式定義了一系列的算法,并將每一個算法封裝起來,而且使他們可以相互替換,讓算法獨立于使用它的客戶而獨立變化。

本例使用場景

例如神機妙算的諸葛亮,他的每個錦囊,就是一個策略,現(xiàn)在諸葛亮給了關(guān)羽三個錦囊——錦囊A,錦囊B,錦囊C,告訴關(guān)羽如果敵軍數(shù)量在一萬到三萬以內(nèi),打開錦囊A;敵軍數(shù)量在三萬到五萬之間,打開錦囊B;還更多的話,打開錦囊C。

角色

環(huán)境(Context)(具體策略的執(zhí)行者——關(guān)羽):持有一個Strategy的引用。

抽象策略(Strategy)(錦囊接口或者抽象類):這是一個抽象角色,通常由一個接口或抽象類實現(xiàn)。此角色給出所有的具體策略類所需的接口。

具體策略(ConcreteStrategy)(具體的錦囊類):包裝了相關(guān)的算法或行為。

具體實現(xiàn)
//抽象策略類 錦囊接口
public interface JinNang {
    /**
     * 策略方法 打開錦囊
     */
    public void openJinNang();
}
//具體策略類 錦囊A
public class JinNangA implements JinNang {

    @Override
    public void openJinNang(Integer enermyNum) {
        System.out.println("朝敵軍使用拋擲糞便攻擊,殺敵20%!傷敵數(shù)量為:"+enermyNum*0.2);
    }

}

//具體策略類 錦囊B
public class JinNangB  implements JinNang {

    @Override
    public void openJinNang(Integer enermyNum) {
        System.out.println("朝敵軍播放難忘今宵以瓦解敵軍意志,殺敵50%!傷敵數(shù)量為:"+enermyNum*0.5);
    }

}

//具體策略類 錦囊C
public class JinNangC implements JinNang {

    @Override
    public void openJinNang(Integer enermyNum) {
        System.out.println("丫的還不快跑!?");
    }

}
//環(huán)境角色類--關(guān)羽
public class GuanYu{
    //持有一個具體策略的對象
    private JinNang jinNang;

    /**
     * 策略方法
     */
    public void fight(Integer enermyNum){
        if (enermyNum >10000&enermyNum<30000){
            jinNang=new JinNangA();
        } else if (enermyNum >30000&enermyNum<50000){
            jinNang=new JinNangB();
        } else{
            jinNang=new JinNangC();
        }
        jinNang.openJinNang(enermyNum);
    }

}
測試

好的,現(xiàn)在我們的關(guān)羽跨上赤兔馬,拎起青龍刀,來到了陣前,對面分別出動了兩個師,四個師,十個師的兵力干他!即便如此,我們的小英雄也A了上去!

public static void main(String[] args) {
        GuanYu guanYu = new GuanYu();
        guanYu.fight(20000);
        guanYu.fight(40000);
        guanYu.fight(100000);
    }

測試結(jié)果
顯而易見,測試結(jié)果是:

朝敵軍使用拋擲糞便攻擊,殺敵20%!傷敵數(shù)量為:4000.0
朝敵軍播放難忘今宵以瓦解敵軍意志,殺敵50%!傷敵數(shù)量為:20000.0
丫的還不快跑!?
模式總結(jié)

策略模式的重心不是如何實現(xiàn)算法,而是如何組織、調(diào)用這些算法,從而讓程序結(jié)構(gòu)更靈活,具有更好的維護性和擴展性。

運行期間,策略模式在每一個時刻只能使用一個具體的策略實現(xiàn)對象,雖然可以動態(tài)地在不同的策略實現(xiàn)中切換,但是同時只能使用一個。

優(yōu)劣 優(yōu)點

策略模式提供了管理相關(guān)的算法族的辦法。策略類的等級結(jié)構(gòu)定義了一個算法或行為族。恰當使用繼承可以把公共的代碼移到父類里面,從而避免代碼重復。

使用策略模式可以避免使用多重條件(if-else)語句。多重條件語句不易維護,它把采取哪一種算法或采取哪一種行為的邏輯與算法或行為的邏輯混合在一起,統(tǒng)統(tǒng)列在一個多重條件語句里面,比使用繼承的辦法還要原始和落后。

缺點

客戶端必須知道所有的策略類,并自行決定使用哪一個策略類。這就意味著客戶端必須理解這些算法的區(qū)別,以便適時選擇恰當?shù)乃惴悺Q言之,策略模式只適用于客戶端知道算法或行為的情況。

由于策略模式把每個具體的策略實現(xiàn)都多帶帶封裝成為類,如果備選的策略很多的話,那么對象的數(shù)目就會很可觀。

3 外觀模式 定義

外觀模式(Facade Pattern)又稱為門面模式,它為系統(tǒng)中的一組接口提供一個一致的界面,此模式定義了一個高層接口,這個接口使得子系統(tǒng)更加容易使用。該模式可以隱藏系統(tǒng)的復雜性,提供了客戶端請求的簡化方法和對現(xiàn)有系統(tǒng)類方法的委托調(diào)用。

本例使用場景

蜀漢集團總經(jīng)理諸葛亮為了光復中原,推出了“三個臭皮匠”陣法,由關(guān)羽張飛趙云壓陣,在砍人的時候充當蜀軍的門面。于是在群P的時候,對于他們的客戶(敵人)來說,和外觀(陣法)交互(打架)并不需要知道他們內(nèi)在的細節(jié),許多繁瑣的邏輯,已經(jīng)被門面封裝了。

角色

門面(facade)角色(三個臭皮匠陣法):外觀模式的核心。它被客戶角色調(diào)用,它熟悉子系統(tǒng)的功能。內(nèi)部根據(jù)客戶角色的需求預定了幾種功能的組合。

子系統(tǒng)(Subsystem)角色(關(guān)張趙三個子系統(tǒng)):子系統(tǒng)類,實現(xiàn)子系統(tǒng)的功能,處理外觀類指派的任務,注意子系統(tǒng)類不含有外觀類的引用。

具體實現(xiàn)

我們先來定義三個子系統(tǒng):關(guān)張趙

/**
 * 子系統(tǒng)關(guān)羽
 */
public class GuanYu {
    //剪刀
    public void jianDao(){
        System.out.println("關(guān)羽出剪刀");
    }
    public void shiTou(){
        System.out.println("關(guān)羽出石頭");
    }
    public void bu(){
        System.out.println("關(guān)羽出布");
    }
}
/**
 * 子系統(tǒng)趙云
 */
public class ZhaoYun{
    //剪刀
    public void jianDao(){
        System.out.println("趙云出剪刀");
    }
    public void shiTou(){
        System.out.println("趙云出石頭");
    }
    public void bu(){
        System.out.println("趙云出布");
    }
}
/**
 * 子系統(tǒng)張飛
 */
public class ZhangFei {
    //剪刀
    public void jianDao(){
        System.out.println("張飛出剪刀");
    }
    public void shiTou(){
        System.out.println("張飛出石頭");
    }
    public void bu(){
        System.out.println("張飛出布");
    }
}

接下來定義統(tǒng)一的外觀類——三個臭皮匠陣法,這個陣法有三個絕技,青龍騰,白龍騰和黑龍騰,至于技能內(nèi)到底怎么實現(xiàn)的,你們這些凡人就不要在意了,總之發(fā)動起來,天上都是龍,你們只要負責喊666就可以了。

public class ThreeChouPiJiang{
    private GuanYu guanYu;
    private ZhangFei zhangFei;
    private ZhaoYun zhaoYun;
    ThreeChouPiJiang(){
        guanYu =new GuanYu();
        zhangFei = new ZhangFei();
        zhaoYun = new ZhaoYun();
    }
    //青龍騰
    public void qingLongTeng(){
        zhangFei.bu();
        zhaoYun.bu();
        guanYu.shiTou();
        System.out.println("青龍騰:關(guān)羽輸了,關(guān)羽出去砍人;");
        System.out.println("BO~BO~BO~經(jīng)費燃燒中~ =============");
    }
    //黑龍騰
    public void heiLongTeng(){
        guanYu.bu();
        zhaoYun.bu();
        zhangFei.shiTou();
        System.out.println("黑龍騰:張飛輸了,張飛出去砍人;");
        System.out.println("BO~BO~BO~經(jīng)費燃燒中~ =============");
    }
    //白龍騰
    public void baiLongTeng(){
        guanYu.bu();
        zhangFei.bu();
        zhaoYun.shiTou();
        System.out.println(":趙云輸了,趙云出去砍人;");
        System.out.println("BO~BO~BO~經(jīng)費燃燒中~ =============");
    }
}
測試

好了,我們的陣法已經(jīng)定義好了,現(xiàn)在諸葛亮意氣風發(fā),決定要北伐中原,我們的三個臭皮匠陣法,開始發(fā)揮威力:

public static void main(String[] args) {
    ThreeChouPiJiang threeChouPiJiang = new ThreeChouPiJiang();
    ThreeChouPiJiang threeChouPiJiang = new ThreeChouPiJiang();
    threeChouPiJiang.baiLongTeng();
    threeChouPiJiang.qingLongTeng();
    threeChouPiJiang.heiLongTeng();
}

測試結(jié)果:

關(guān)羽出布
張飛出布
趙云出石頭
白龍騰:趙云輸了,趙云出去砍人;
BO~BO~BO~經(jīng)費燃燒中~ =============
張飛出布
趙云出布
關(guān)羽出石頭
青龍騰:關(guān)羽輸了,關(guān)羽出去砍人;
BO~BO~BO~經(jīng)費燃燒中~ =============
關(guān)羽出布
趙云出布
張飛出石頭
黑龍騰:張飛輸了,張飛出去砍人;
BO~BO~BO~經(jīng)費燃燒中~ =============

威力果然是十分驚人啊!對于敵人而言,他們只知道三個臭皮匠陣法使用了絕招,根本不會知道絕招內(nèi)部居然是這三個貨用剪刀石頭布搞出來的。在頂級特效的加持下,這個門面還是十分整潔十分威風十分唬人的。

模式總結(jié)

外觀模式的目的不是給予子系統(tǒng)添加新的功能接口,而是為了讓外部減少與子系統(tǒng)內(nèi)多個模塊的交互,松散耦合,從而讓外部能夠更簡單地使用子系統(tǒng)。
外觀模式的本質(zhì)是:封裝交互,簡化調(diào)用。

優(yōu)劣 優(yōu)點

松散耦合,使得客戶端和子系統(tǒng)之間解耦,讓子系統(tǒng)內(nèi)部的模塊功能更容易擴展和維護;

簡單易用,客戶端根本不需要知道子系統(tǒng)內(nèi)部的實現(xiàn),或者根本不需要知道子系統(tǒng)內(nèi)部的構(gòu)成,它只需要跟Facade類交互即可。

更好的劃分訪問層次,有些方法是對系統(tǒng)外的,有些方法是系統(tǒng)內(nèi)部相互交互的使用的。子系統(tǒng)把那些暴露給外部的功能集中到門面中,這樣就可以實現(xiàn)客戶端的使用,很好的隱藏了子系統(tǒng)內(nèi)部的細節(jié)。

缺點

在不引入抽象外觀類的情況下,增加新的子系統(tǒng)可能需要修改外觀類或客戶端的源代碼,違背了“開閉原則”

4 觀察者模式 定義

在對象之間定義了一對多的依賴,這樣一來,當一個對象改變狀態(tài),依賴它的對象會收到通知并自動更新。
簡單來說,其實就是發(fā)布訂閱模式,發(fā)布者發(fā)布信息,訂閱者獲取信息,訂閱了就能收到信息,沒訂閱就收不到信息。

本例使用場景

例如微信公眾號服務,不定時發(fā)布一些消息,關(guān)注公眾號就可以收到推送消息,取消關(guān)注就收不到推送消息。

角色

抽象被觀察者(公眾號接口):也就是一個抽象主題,它把所有對觀察者對象的引用保存在一個集合中,每個主題都可以有任意數(shù)量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者角色。一般用一個抽象類和接口來實現(xiàn)。

抽象觀察者(訂閱人接口):為所有的具體觀察者定義一個接口,在得到主題通知時更新自己。

具體被觀察者(公眾號):也就是一個具體的主題,在集體主題的內(nèi)部狀態(tài)改變時,所有登記過的觀察者發(fā)出通知。

具體觀察者(訂閱人):實現(xiàn)抽象觀察者角色所需要的更新接口,一邊使本身的狀態(tài)與制圖的狀態(tài)相協(xié)調(diào)。

具體實現(xiàn)
/***
 * 抽象被觀察者接口
 * 聲明了添加、刪除、通知觀察者方法
 */
public interface Observerable {
    
    public void registerObserver(Observer o);//新增訂閱人
    public void removeObserver(Observer o);//刪除訂閱人
    public void notifyObserver();//發(fā)布消息
    
}
/***
 * 抽象觀察者
 * 定義了一個update()方法,當被觀察者調(diào)用notifyObservers()方法時,觀察者的update()方法會被回調(diào)。
 */
public interface Observer {
    public void update(String message);//更新消息
}
/**
 * 被觀察者,也就是微信公眾號服務
 * 實現(xiàn)了Observerable接口,對Observerable接口的三個方法進行了具體實現(xiàn)
 */
public class WechatServer implements Observerable {
    //注意到這個List集合的泛型參數(shù)為Observer接口,設計原則:面向接口編程而不是面向?qū)崿F(xiàn)編程
    private List list;
    private String message;
    
    public WechatServer() {
        list = new ArrayList();
    }
    
    @Override
    public void registerObserver(Observer o) {
        
        list.add(o);
    }
    
    @Override
    public void removeObserver(Observer o) {
        if(!list.isEmpty())
            list.remove(o);
    }
    
    //遍歷通知
    @Override
    public void notifyObserver() {
        for(int i = 0; i < list.size(); i++) {
            Observer oserver = list.get(i);
            oserver.update(message);
        }
    }
    
    public void setInfomation(String s) {
        this.message = s;
        System.out.println("微信服務更新消息: " + s);
        //消息更新,通知所有觀察者
        notifyObserver();
    }
}
/**
 * 觀察者
 * 實現(xiàn)了update方法
 */
public class User implements Observer {

    private String name;
    private String message;
    
    public User(String name) {
        this.name = name;
    }
    
    @Override
    public void update(String message) {
        this.message = message;
        read();
    }
    
    public void read() {
        System.out.println(name + " 收到推送消息: " + message);
    }
    
}
測試

首先注冊了三個用戶,ZhangSan、LiSi、WangWu。公眾號發(fā)布了一條消息"PHP是世界上最好用的語言!",三個用戶都收到了消息。

用戶ZhangSan看到消息后頗為震驚,果斷取消訂閱,這時公眾號又推送了一條消息,此時用戶ZhangSan已經(jīng)收不到消息,其他用戶

還是正常能收到推送消息。

public class Test {
    
    public static void main(String[] args) {
        WechatServer server = new WechatServer();
        
        Observer userZhang = new User("ZhangSan");
        Observer userLi = new User("LiSi");
        Observer userWang = new User("WangWu");
        
        server.registerObserver(userZhang);
        server.registerObserver(userLi);
        server.registerObserver(userWang);
        server.setInfomation("PHP是世界上最好用的語言!");
        
        System.out.println("----------------------------------------------");
        server.removeObserver(userZhang);
        server.setInfomation("JAVA是世界上最好用的語言!");
        
    }
}

測試結(jié)果:

5 責任鏈模式 定義

使多個對象都有機會處理同一個請求,從而避免請求的發(fā)送者和接收者之間的耦合關(guān)系。將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理它為止。

為完成同一個請求,如果存在多個請求處理器以及未知請求處理器個數(shù)或者請求處理器可動態(tài)配置的情況下,可以考慮使用責任鏈模式。

適用于: 鏈條式處理事情。工作流程化、消息處理流程化、事物流程化;

本例使用場景

圣斗士星矢,五小強們勇闖黃金十二宮,我們可以把這十二宮,看成是十二個處理者,他們用一條鏈串起來。

角色

Handler抽象處理者(黃金圣斗士): 定義一個處理請求的接口,提供對后續(xù)處理者的引用

ConcreteHandler具體處理者(如白羊座圣斗士): 抽象處理者的子類,處理用戶請求,可選將請求處理掉還是傳給下家;在具體處理者中可以訪問鏈中下一個對象,以便請求的轉(zhuǎn)發(fā)。

具體實現(xiàn)

我們先來定義一個抽象的黃金圣斗士的抽象類:

public interface GoldenWarrior {
    void fight(String xiaoQiangName,String response,GoldenWarriorChain chain);
}

我們定義一個白羊座圣斗士:

public class AriesWorrior implements GoldenWarrior{
    @Override
    public void fight(String request, String response, GoldenWarriorChain chain) {

        System.out.println(request+"fight with AriesWorrior,AriesWorrior lose");

        chain.fight(request, response, chain);

        System.out.println(response+" reback to AriesWorrior here!");
    }
}

再來定義一個獅子座圣斗士

public class LeoWorrior implements GoldenWarrior{
    @Override
    public void fight(String request, String response, GoldenWarriorChain chain) {

        System.out.println(request+"fight with LeoWorrior,LeoWorrior lose");

        chain.fight(request, response, chain);

        System.out.println(response+" reback to LeoWorrior here!");
    }
}

然后,是我們的責任鏈對象,或者說是我們例子里面的 十二宮(其實我們就實現(xiàn)了兩宮)對象

public class GoldenWarriorChain implements GoldenWarrior{
    //十二宮的圣斗士們
    private List goldenWarriors=new ArrayList();
    //目前到哪個宮了
    private int index;

    public GoldenWarriorChain addWorrior(GoldenWarrior warrior){
        this.goldenWarriors.add(warrior);
        return this;
    }

    public void fight(String request, String response,GoldenWarriorChain chain) {

        if(index==goldenWarriors.size())
            return;//如果鏈條里沒有filter或是鏈條里的filter都調(diào)用過了(有點象遞歸)

        goldenWarriors.get(index++).fight(request, response, chain);
    }
}
測試
    public static void  main(String[] a){
        GoldenWarriorChain goldenWarriorChain = new GoldenWarriorChain();
        goldenWarriorChain.addWorrior(new LeoWorrior());
        goldenWarriorChain.addWorrior(new AriesWorrior());

        goldenWarriorChain.fight("星矢","",goldenWarriorChain);
    }
結(jié)果
星矢fight with LeoWorrior,LeoWorrior lose
星矢fight with AriesWorrior,AriesWorrior lose
reback to AriesWorrior here!
reback to LeoWorrior here!

因為String是不可變對象,故而,response和request沒能在調(diào)用后被自動傳遞至下一層,或者遞歸后被自動帶回上一層(實際上我們也沒有對它進行過處理,只是打印出來而已),如果response和request是對象的話,上層對象就能得到下層的結(jié)果,不過我們的核心在不在這,無足輕重。

優(yōu)缺點 優(yōu)點:

1。責任的分擔。每個類只需要處理自己該處理的工作(不該處理的傳遞給下一個對象完成),明確各類的責任范圍,符合類的最小封裝原則。
2。可以根據(jù)需要自由組合工作流程。如工作流程發(fā)生變化,可以通過重新分配對象鏈便可適應新的工作流程。
3。類與類之間可以以松耦合的形式加以組織。

缺點:

因為處理時以鏈的形式在對象間傳遞消息,根據(jù)實現(xiàn)方式不同,有可能會影響處理的速度。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/69087.html

相關(guān)文章

  • 黑科技實驗室 - 收藏集 - 掘金

    摘要:我們團隊在屏幕直播方案掘金項目需求是實時同步手機屏幕畫面至瀏覽器。由于引入了對框架的重大改進,因此只有通過支持庫的讓所有以上的設上如何實現(xiàn)矩形區(qū)域截屏掘金對屏幕進行截屏并裁剪有兩種方式早截圖和晚截圖。 從框架層分析如何啟動未注冊的 Activity - Android - 掘金本文關(guān)鍵詞:Binder、AMS、ActivityThread、Handler、Java 反射 引言要解決這個...

    Clect 評論0 收藏0
  • 淺談 JS 創(chuàng)建對象的 8 模式

    摘要:模式工廠模式構(gòu)造器模式通過對象實現(xiàn)模式構(gòu)造器與原型方式的混合模式動態(tài)原型模式混合工廠模式模式字面量的表現(xiàn)形式等價于即以對象為一個原型模板新建一個以這個原型模板為原型的對象區(qū)別創(chuàng)建一個原型為的對象在里查看各個新建對象的區(qū)別可以看出前種模式創(chuàng)建 Objct 模式 工廠模式 構(gòu)造器模式 通過 Function 對象實現(xiàn) prototype 模式 構(gòu)造器與原型方式的混合模式 動態(tài)原型模式 混...

    caoym 評論0 收藏0
  • web 直播流的解析

    摘要:反正就是相反的意思了異或當兩者中只有一個那么結(jié)果才為。將指定根據(jù)的標識轉(zhuǎn)換成為進制。當創(chuàng)建實例的構(gòu)造函數(shù)時,內(nèi)部會同時創(chuàng)建一個用來作為數(shù)據(jù)的存儲。不過,根據(jù)上面的構(gòu)造函數(shù)上看,其實,可以將一整個拆成不同的進行讀取。 Web 進制操作是一個比較底層的話題,因為平常做業(yè)務的時候根本用不到太多,或者說,根本用不到。 老鐵,沒毛病 那什么情況會用到呢? canvas websocket fi...

    williamwen1986 評論0 收藏0

發(fā)表評論

0條評論

0xE7A38A

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<