Android設(shè)計(jì)模式交流心得

文章摘要:
1出牧、設(shè)計(jì)模式的應(yīng)用在于其要達(dá)到的目的。
2歇盼、Adapter是適配器模式舔痕?策略模式?
3、Context是裝飾者模式嗎?


今天和小伙伴一起交流設(shè)計(jì)模式撵溃,有些心得,歡迎小伙伴拍磚~

一啸如、抽象工廠和工廠模式的異同點(diǎn)。

抽象工廠中有工廠方法的影子氮惯。抽象工廠需要獲取一系列對(duì)象的相關(guān)依賴叮雳,那么就需要定義一組接口,每個(gè)接口返回一個(gè)【對(duì)象依賴】筐骇。
1债鸡、相同點(diǎn)

  • a、都是對(duì)象創(chuàng)建模式铛纬,即:都需要返回對(duì)象厌均。
  • b、對(duì)于客戶端來說告唆,都封裝了創(chuàng)建對(duì)象的細(xì)節(jié)棺弊。
  • c、擁有超類型父類擒悬,讓客戶端不需要關(guān)注創(chuàng)建的具體對(duì)象模她。

2、異同點(diǎn)

  • a懂牧、返回對(duì)象數(shù)目侈净。工廠方法返回一個(gè)對(duì)象尊勿,抽象工廠返回對(duì)象的相關(guān)依賴集合。

在Android中Abstract Phone.java 是抽象超類型畜侦,其具體的子類中存在獲取getIccCard元扔、CommandsInterfacegetCallTracker等一系列Telphony相關(guān)對(duì)象依賴旋膳。從這個(gè)層面上來說澎语,這是一個(gè)抽象工廠。如果從單純的創(chuàng)建IccCard一個(gè)對(duì)象來說验懊,此就是工廠方法擅羞。

    /**
     * Returns the ICC card interface for this phone, or null
     * if not applicable to underlying technology.
     */
    public IccCard getIccCard() {
        return null;
        //throw new Exception("getIccCard Shouldn't be called from Phone");
    }

    /**
    * Get call tracker
    */
    public CallTracker getCallTracker() {
        return null;
    }

二、適配器模式

適配器模式類似動(dòng)畫片里的“變身/偽裝”技能义图,將自身偽裝成敵人减俏,從而混過敵人的耳目。 在Android中歌溉,適配器模式的使用垄懂,最常被大家提到的就屬于ListView和ListAdapter骑晶,但也要看怎么定位其工作流程:

  • 1痛垛、策略模式的身影。我們通過ListView#setAdapter(ListAdapter adapter)來將adapter設(shè)定給ListView桶蛔,針對(duì)不同類型的數(shù)據(jù)源以及具體的使用場景匙头,adapter的實(shí)現(xiàn)類可以是ArrayAdapter、BaseAdapter仔雷、CursorAdapter蹂析,從這個(gè)層面來講,ListView和Adapter之間屬于策略模式碟婆。

設(shè)計(jì)原則:
針對(duì)超類型編程电抚,不要依賴具體實(shí)現(xiàn)。在ListView中竖共,ListAdapter屬于超類型蝙叛,對(duì)ListView來說不用去關(guān)心到底那個(gè)子類實(shí)> 現(xiàn)了ListAdapter。

  • 2公给、模板方法的身影借帘。BaseAdapter是一個(gè)超類型類,繼承自ListAdapter淌铐。在BaseAdapter中肺然,存在getDropDownViewisEmpty等模板算法骨架腿准,而將getView际起、getCount放到子類中去實(shí)現(xiàn)。{有點(diǎn)牽強(qiáng),不如Activity生命周期方法更生動(dòng)}
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        return getView(position, convertView, parent);
    }
    
    public boolean isEmpty() {
        return getCount() == 0;
    }

三街望、裝飾者模式

在跟小伙伴聊天的過程中倦沧,提到Context是不是裝飾者模式的一個(gè)應(yīng)用,我們也在這里產(chǎn)生了分歧它匕,從隱隱約約感覺是展融,但從小伙伴描述的工作流程來看,其敘述的工作流程并不是裝飾者模式豫柬。

裝飾者模式的目的在于為類增加功能告希、擴(kuò)展對(duì)象的行為,在這方面裝飾者模式提供了比繼承更有彈性的替代方案烧给。

那么Context在Android中的應(yīng)用是不是裝飾者模式的范例燕偶,我們從實(shí)現(xiàn)的角度來看下答案:

  • 3.1、Context相關(guān)類對(duì)象介紹础嫡。Context對(duì)象是Abstract 超類型指么,其中包含了很多具體的Context對(duì)象的依賴,從這方面來說榴鼎,Context也是抽象工廠伯诬。
public abstract class Context {
    public abstract Context getApplicationContext();
    public abstract Resources getResources();

    /** Return PackageManager instance to find global package information. */
    public abstract PackageManager getPackageManager();

    /** Return a ContentResolver instance for your application's package. */
    public abstract ContentResolver getContentResolver();

    /**
     * Returns an AssetManager instance for the application's package.
     * <p>
     * <strong>Note:</strong> Implementations of this method should return
     * an AssetManager instance that is consistent with the Resources instance
     * returned by {@link #getResources()}. For example, they should share the
     * same {@link Configuration} object.
     *
     * @return an AssetManager instance for the application's package
     * @see #getResources()
     */
    public abstract AssetManager getAssets();
}

ContextWrapper中有一個(gè)成員變量Context,通過attachBaseContext可以為其賦值巫财。

public class ContextWrapper extends Context {
    Context mBase;

    protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
    }
}

public class ContextThemeWrapper extends ContextWrapper {
    @Override
    protected void attachBaseContext(Context newBase) {
        super.attachBaseContext(newBase);
    }
}
  • 3.2盗似、Context對(duì)象的創(chuàng)建。
    PATH:frameworks/base/core/java/android/app/ActivityThread.java
    在ActivityThread中平项,可以看到赫舒,Context對(duì)象來自ComtextImpl對(duì)象的實(shí)例化構(gòu)建。
    private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
        int displayId = Display.DEFAULT_DISPLAY;
        ContextImpl appContext = ContextImpl.createActivityContext(
                this, r.packageInfo, r.token, displayId, r.overrideConfig);
        appContext.setOuterContext(activity);
        Context baseContext = appContext;
        return baseContext;
    }
  • 3.2闽瓢、Activity的創(chuàng)建接癌。
    首先:Activity繼承自ContextThemeWrapper。
    其次:Activity是在ActivityThread.java中通過類裝載器創(chuàng)建的扣讼。
    PATH:frameworks/base/core/java/android/app/ActivityThread.java
    public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        return (Activity)cl.loadClass(className).newInstance();
    }

這個(gè)時(shí)候缺猛,就創(chuàng)建了一個(gè)Activity對(duì)象,也是一個(gè)Context對(duì)象届谈。
最后枯夜,調(diào)用attach方法,將Context傳入Activity中艰山。在Activity中湖雹,attachBaseContext就是上面ContextThemeWrapper的實(shí)現(xiàn)。
PATH:frameworks/base/core/java/android/app/ActivityThread.java

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window);
}

Activity.java

    final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window) {
        attachBaseContext(context);
}

綜述:
我們?cè)贏ctivity中曙搬,直接通過Activity.this或者this來直接使用Activity的Context對(duì)象,這個(gè)Context對(duì)象其實(shí)就是ContextThemeWrapper摔吏,相比較于ContextImpl實(shí)例化對(duì)象鸽嫂,ContextThemeWrapper提供了對(duì)Theme主題的支持,讓Context對(duì)象的功能更加強(qiáng)大征讲。
從這個(gè)角度來說据某,Conetxt及其ContextThemeWrapper是裝飾者模式的應(yīng)用案例。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末诗箍,一起剝皮案震驚了整個(gè)濱河市癣籽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌滤祖,老刑警劉巖筷狼,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異匠童,居然都是意外死亡埂材,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門汤求,熙熙樓的掌柜王于貴愁眉苦臉地迎上來俏险,“玉大人,你說我怎么就攤上這事扬绪∈溃” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵勒奇,是天一觀的道長预鬓。 經(jīng)常有香客問我巧骚,道長赊颠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任劈彪,我火速辦了婚禮竣蹦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘沧奴。我一直安慰自己痘括,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布滔吠。 她就那樣靜靜地躺著纲菌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪疮绷。 梳的紋絲不亂的頭發(fā)上翰舌,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音冬骚,去河邊找鬼椅贱。 笑死懂算,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的庇麦。 我是一名探鬼主播计技,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼山橄!你這毒婦竟也來了垮媒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤航棱,失蹤者是張志新(化名)和其女友劉穎涣澡,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丧诺,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡入桂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了驳阎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抗愁。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖呵晚,靈堂內(nèi)的尸體忽然破棺而出蜘腌,到底是詐尸還是另有隱情,我是刑警寧澤饵隙,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布撮珠,位于F島的核電站,受9級(jí)特大地震影響金矛,放射性物質(zhì)發(fā)生泄漏芯急。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一驶俊、第九天 我趴在偏房一處隱蔽的房頂上張望娶耍。 院中可真熱鬧,春花似錦饼酿、人聲如沸榕酒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽想鹰。三九已至,卻和暖如春药版,著一層夾襖步出監(jiān)牢的瞬間辑舷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來泰國打工刚陡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惩妇,地道東北人株汉。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像歌殃,于是被迫代替她去往敵國和親乔妈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

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