結構型設計模式之代理, 享元, 門面, 橋接

1:代理模式(Proxy)

情景:一個客戶不想或者不能夠直接引用一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用厢钧。

給某一個對象提供一個代理對象皿哨,并由代理對象控制對原對象的引用长酗。

靜態(tài)代理

可以做到在不修改目標對象的功能前提下,對目標對象調用铜涉,以及對目標功能擴展智玻。

缺點:因為代理對象需要與目標對象實現(xiàn)一樣的接口,所以會有很多代理類,類太多或者接口增加方法,目標對象與代理對象都要維護, 那么就有了動態(tài)代理芙代。

Android 靜態(tài)代理實例

插件化框架 dynamic-load-apk的核心思想可以總結為兩個字:代理吊奢。通過在 Manifest 中注冊代理組件Activity或者Service等,當啟動插件組件時首先啟動一個代理組件纹烹,然后通過這個代理組件來構建页滚、啟動插件組件對應的方法就OK了。

參考 :
Android 插件化框架 DynamicLoadApk 源碼解析

動態(tài)代理

代理對象,不需要實現(xiàn)接口,利用API的java.lang.reflect.Proxy類中方法newProxyInstances反射調用目標對象的方法铺呵,但是目標對象一定要實現(xiàn)接口,否則不能用動態(tài)代理裹驰。

代理對象

public class ProxyFactory {
  
  private Object target;

  public ProxyFactory(Object target) {
      this.target = target;
  }

  public Object getProxyInstance(){

      return Proxy.newProxyInstance(
                target.getClass().getClassLoader()
              , target.getClass().getInterfaces()
              , new InvocationHandler() {
                  @Override
                  public Object invoke(Object o, Method method, Object[] objects) throws Throwable {

                      System.out.println("開始事務2");

                      //執(zhí)行目標對象方法
                      Object returnValue = method.invoke(target, objects);

                      return returnValue;
                  }
              });
  }
}

客戶實現(xiàn)

public class client {

    public static void main(String[] args){

        // 目標對象
        AbstractObject abstractObject = new RealObject();

        // 【原始的類型 class com.decoration.lib.proxy.sample2.RealObject】
        System.out.println(abstractObject.getClass());

        // 給目標對象,創(chuàng)建代理對象
        AbstractObject proxyObject = (AbstractObject) new ProxyFactory(abstractObject).getProxyInstance();

        // 【 class com.sun.proxy.$Proxy0 】 內(nèi)存中動態(tài)生成的代理對象
        System.out.println(proxyObject.getClass());

        // 執(zhí)行方法   【代理對象】
        proxyObject.operation();

    }
}

參考:
《Java的三種代理模式》
《Java設計模式——代理模式實現(xiàn)及原理》

2: 享元模式(Flyweight)

主要作用就是復用大對象(重量級對象)片挂,以節(jié)省內(nèi)存空間和對象創(chuàng)建時間幻林。

顧名思義:共享元對象。如果在一個系統(tǒng)中存在多個相同的對象宴卖,那么只需要共享一份對象的拷貝滋将,而不必為每一次使用創(chuàng)建新的對象。

public class FlyweightFactory {
    private Map<Character,Flyweight> files = new HashMap<Character,Flyweight>();
    
    public Flyweight factory(Character state){
        //先從緩存中查找對象
        Flyweight fly = files.get(state);
        if(fly == null){
            //如果對象不存在則創(chuàng)建一個新的Flyweight對象
            fly = new ConcreteFlyweight(state);
            //把這個新的Flyweight對象添加到緩存中
            files.put(state, fly);
        }
        return fly;
    }
}

優(yōu)點:大幅度地降低內(nèi)存中對象的數(shù)量症昏,節(jié)省內(nèi)存空間。
缺點:使得系統(tǒng)更加復雜父丰。為了使對象可以共享肝谭,需要將一些狀態(tài)外部化掘宪,這使得程序的邏輯復雜化。將享元對象的狀態(tài)外部化攘烛,而讀取外部狀態(tài)使得運行時間稍微變長魏滚。

應用場景:
1:享元模式由于其共享的特征,可以在任何“池”中操作坟漱,比如:線程池鼠次,數(shù)據(jù)庫連接池。
2:String類的設計也是享元模式(String對象是final類型芋齿,對象一旦創(chuàng)建就不可改變)

參考:
java設計模式---享元模式
《JAVA與模式》之享元模式
《Android源碼設計模式》--享元模式

3: 門面模式(外觀模式)

設立一個門面對象腥寇,使客戶訪問門面就可以了,不需要單獨調用里面不同的子系統(tǒng)模塊

初學者往往以為通過繼承一個門面類便可在子系統(tǒng)中加入新的行為觅捆,這是錯誤的赦役。門面模式的用意是為子系統(tǒng)提供一個集中化和簡化的溝通管道,而不能向子系統(tǒng)加入新的行為栅炒。

缺點:不符合開閉原則掂摔,如果要改東西很麻煩,繼承重寫都不合適赢赊。

參考: 《JAVA與模式》之門面模式

4:橋接模式(橋梁Bridge)

主要應對:由于實際的需要乙漓,某個類具有兩個或兩個以上的維度變化,如果只是用繼承將無法實現(xiàn)這種需要释移,或者使得設計變得相當臃腫叭披。

把抽象(abstraction)與行為實現(xiàn)(implementation)分離開來,從而可以保持各部分的獨立性以及應對它們的功能擴展秀鞭。

下面的AbstractComputer類就是橋接類趋观,AbstractComputer的具體實現(xiàn)是一個維度,其中的CpuAbility又是一個維度锋边,通過橋接類連接了兩個維度皱坛。

public abstract class AbstractComputer{    
     CpuAbility cpuAbility;    
     public AbstractComputer(CpuAbility cpuAbility){
         this.cpuAbility=cpuAbility;
         
     }   
     public abstract void checkPcAbility();  
 } 

參考: 《JAVA與模式》之橋接模式

另外:
其中對象的適配器模式是結構型各種模式的起源:

image.png

參考: Java之美[從菜鳥到高手演變]之設計模式二

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市豆巨,隨后出現(xiàn)的幾起案子剩辟,更是在濱河造成了極大的恐慌,老刑警劉巖往扔,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贩猎,死亡現(xiàn)場離奇詭異,居然都是意外死亡萍膛,警方通過查閱死者的電腦和手機吭服,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蝗罗,“玉大人艇棕,你說我怎么就攤上這事蝌戒。” “怎么了沼琉?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵北苟,是天一觀的道長。 經(jīng)常有香客問我打瘪,道長友鼻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任闺骚,我火速辦了婚禮彩扔,結果婚禮上,老公的妹妹穿的比我還像新娘葛碧。我一直安慰自己借杰,他們只是感情好,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布进泼。 她就那樣靜靜地躺著蔗衡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪乳绕。 梳的紋絲不亂的頭發(fā)上绞惦,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機與錄音洋措,去河邊找鬼济蝉。 笑死,一個胖子當著我的面吹牛菠发,可吹牛的內(nèi)容都是我干的王滤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼滓鸠,長吁一口氣:“原來是場噩夢啊……” “哼雁乡!你這毒婦竟也來了?” 一聲冷哼從身側響起糜俗,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤踱稍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后悠抹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體珠月,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年楔敌,在試婚紗的時候發(fā)現(xiàn)自己被綠了啤挎。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡卵凑,死狀恐怖侵浸,靈堂內(nèi)的尸體忽然破棺而出旺韭,到底是詐尸還是另有隱情氛谜,我是刑警寧澤掏觉,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站值漫,受9級特大地震影響澳腹,放射性物質發(fā)生泄漏。R本人自食惡果不足惜杨何,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一酱塔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧危虱,春花似錦羊娃、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至弥雹,卻和暖如春垃帅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背剪勿。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工贸诚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人厕吉。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓酱固,卻偏偏與公主長得像,于是被迫代替她去往敵國和親头朱。 傳聞我的和親對象是個殘疾皇子运悲,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容