Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> 《Android源碼設計模式解析與實戰》讀書筆記(二十一)

《Android源碼設計模式解析與實戰》讀書筆記(二十一)

編輯:關於android開發

《Android源碼設計模式解析與實戰》讀書筆記(二十一)


第二十一章、裝飾模式

裝飾模式也稱為包裝模式,是結構型設計模式之一。裝飾模式是一種用於替代繼承技術的一種方案。

1.定義

動態的給一個對象添加一些額外的職責。就增加功能來說,裝飾模式相比生成子類更為靈活。

2.使用場景

(1)需要透明且動態地擴展類的功能時。且在不影響其他對象的情況下。

(2)當不能采用繼承對系統進行擴展時可以使用裝飾模式。比如final類。

3.UML類圖

這裡寫圖片描述

(1)Component:抽象組件。可以是一個接口或抽象類,其充當的就是被裝飾的原始對象。

(2)ConcreteComponent:組件具體實現類,該類是Component類的基本實現,也是我們裝飾的具體對象。

(3)Decorator:抽象裝飾者,其職責就是裝飾我們的組件對象,通過其子類擴展該方法以達到裝飾的目的。其內部一定要有一個指向組件對象的引用。在大多數情況下,該類為抽象類,需要根據不同的裝飾邏輯實現不同的具體子類。

(4)ConcreteDecoratorAConcreteDecoratorB:裝飾著具體實現類。負責向構件添加新的職責。

4.簡單實現

以一個男孩穿衣裝扮為例。實現給男孩在家與出門的穿衣裝扮。

抽象組件類(Component):

public abstract class Person {
    /**
     * Person下有一個穿著的抽象方法 
     */
    public abstract void dressed();
}

具體實現類(ConcreteComponent):表示要裝扮的Boy

public class Boy extends Person{

    @Override
    public void dressed() {
        System.out.println("Boy穿了內衣內褲");
    }

}

抽象裝飾類(Decorator):PersonCloth 表示人所穿著的衣服

public class PersonCloth extends Person{

    protected Person mPerson; //保持一個Person類的引用

    public PersonCloth(Person mPerson) {
        super();
        this.mPerson = mPerson;
    }

    @Override
    public void dressed() {
        mPerson.dressed();
    }
}

出門穿的衣服:

public class OutsideCloth extends PersonCloth{

    public OutsideCloth(Person mPerson) {
        super(mPerson);
    }

    /**
     * 穿短袖 
     */
    private void dressShirt(){
        System.out.println("穿件短袖");
    }

    /**
     * 穿牛仔褲 
     */
    private void dressJean(){
        System.out.println("穿牛仔褲");
    }

    /**
     * 穿鞋子 
     */
    private void dressShoes(){
        System.out.println("穿鞋子 ");
    }

    @Override
    public void dressed() {
        super.dressed();
        dressShirt();
        dressJean();
        dressShoes();
    }

}

在家穿的衣服:

public class HomeCloth extends PersonCloth{

    public HomeCloth(Person mPerson) {
        super(mPerson);
    }

    /**
     * 穿短褲
     */
    private void dressShorts(){
        System.out.println("穿短褲");//在家裡隨便點
    }

    @Override
    public void dressed() {
        super.dressed();
        dressShorts();
    }

}

裝扮:

public class Client {
    public static void main(String[] args) {
        //首先有一個男孩
        Person person = new Boy();

        //在家
        PersonCloth personCloth = new HomeCloth(person);
        personCloth.dressed();
        System.out.println("--------------");
        //出門
        PersonCloth personCloth1 = new OutsideCloth(person);
        personCloth1.dressed();

    }
}

結果

Boy穿了內衣內褲
穿短褲
--------------
Boy穿了內衣內褲
穿件短袖
穿牛仔褲
穿鞋子 

5.Android源碼中的實現

1.Context

Context類在Android中被稱為“上帝對象”,它的本質就是一個抽象類,在裝飾模式中相當於抽象組件,而在內部定義了大量的抽象方法,比如我們經常用到的startActivity方法。而真正實現是在ContextImpl中完成,那麼ContextImpl 就是具體實現類。因為ContextWrapper 繼承於Context ,所以ContextWrapper 就是裝飾者。具體大家可以自行查看源碼。

6.區別

1.與代理模式的區別

(1)裝飾模式是以對客戶端透明的方式擴展對象的功能,是繼承方案的一個替代;而代理模式則是給一個對象提供一個代理對象,並有代理對象來控制對原有對象的引用。

(2)裝飾模式應該為所裝飾的對象增強功能;代理模式是對代理對象施加控制,不對對象本身功能進行增強。

2.與適配器模式的區別

適配器模式是用新接口來調用原接口,原接口對新系統是不可見的;裝飾模式增強了其他對象的功能而同時又不改變它的接口。

7.總結

在實際開發中我們應該寫過如下代碼:其實這些新增方法的調用就類似裝飾模式中的裝飾者的職責,只不過這裡我們沒有保持對組件類的引用。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //初始化數據
        initData();

        //初始化控件
        initViews();

        //初始化事件
        initEvent();
    }

1.優點

(1)對於擴展一個對象的功能,裝飾模式比繼承更加靈活性,不會導致類的個數急劇增加。

(2)可以通過一種動態的方式在運行時選擇不同的具體裝飾類,從而實現不同的行為。

(3)可以對一個對象進行多次裝飾,通過使用不同的具體裝飾類以及這些裝飾類的排列組合,可以創造出很多不同行為的組合,得到功能更為強大的對象。

(4)具體構件類與具體裝飾類可以獨立變化,用戶可以根據需要增加新的具體構件類和具體裝飾類,原有類庫代碼無須改變,符合“開閉原則”。

2.缺點

(1)使用裝飾模式進行系統設計時將產生很多小對象,這些對象的區別在於它們之間相互連接的方式有所不同,而不是它們的類或者屬性值有所不同,大量小對象的產生勢必會占用更多的系統資源,在一定程序上影響程序的性能。

(2)對於多次裝飾的對象,調試時尋找錯誤可能需要逐級排查,較為繁瑣。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved