設(shè)計模式學(xué)習(xí)筆記03-Singleton模式和Adapter模式

本文主要是看了《設(shè)計模式》做的筆記和思考,在此分享僅代表個人觀點,如有不對的地方歡迎批評和指正。

Singleton(單例)模式

基礎(chǔ)

中心思想是全局只有一個該類的實例,相比全局變量它也有優(yōu)勢:單例模式不會污染命名空間。這種模式是巧妙地利用機制保證了其實例的唯一性,比如我們Java教材上的一個例子:

class Sun{
    private static Sun sun;
    protectc Sun(){}
    public static Sun initialize(){
        if(sun == null){
            sun = new Sun();
        }
        return sun;
    }
}

使用時如下:

Sun onlyOne = Sun::initialize();

此處將Sun的構(gòu)造函數(shù)隱藏了起來,并提供了靜態(tài)方法initialize獲取Sun對象,這個Sun對象是靜態(tài)的,可以保證每次調(diào)用initialize都是返回。

Java中的Protected

由于Java奇怪的權(quán)限制度,Protected修飾的構(gòu)造方法將導(dǎo)致同一個包下的其他類可見,若使用Private修飾則子類也不可見,無法完成實例化。因此在同一個包下,使用Protected有可能出現(xiàn)直接new出單例的風(fēng)險,但是,通過initialize()得到的對象是不受影響的,因為它是一個靜態(tài)變量,從這個角度來說,單例也沒有完全被破壞。

單例模式在多線程下

感謝網(wǎng)友的提醒并提供了他的博客供我參考,多線程下,若兩個線程同時調(diào)用initialize()并都發(fā)現(xiàn)此時sun(上面的代碼)為空,那么就有可能破壞單例,比較好的辦法是加同步鎖,如下所示。

public static synchronized Sun initialize(){
    if(sun == null){
        sun = new Sun();
    }
    return sun;
}

等同于:

public static Sun initialize(){
    synchronized(Sun.class){
        ...
    }
}

不過這樣的聲明可能影響效率(如果這個構(gòu)造方法很大的話),因此可以選擇使用同步代碼塊解決,并且給它個鎖對象。其中,byte[0]就是個開銷很小的鎖對象,參考這篇文章得到。

class Sun{
    private static byte[] lock = new byte[0];
    public static Sun initialize(){
        synchronized(lock){
            if(sun == null){
                sun = new Sun();
            }
            return sun;
        }
    }
}

Adapter(適配器)模式

基礎(chǔ)

該模式的作用是為了“使得原本由于接口不兼容而不能一起工作的那些類可以一起工作”,即將不兼容問題通過一個中間人解決。該模式有兩種類型:類適配器、對象適配器。相比之下,個人覺得對象適配器更加靈活,也更加常見(Android中經(jīng)常需要實現(xiàn)各種BaseAdapter)

類適配器

假設(shè)A、B是兩個不兼容的接口(因為Java中不能多繼承),C為類,則C會同時實現(xiàn)A、B兩接口,并解決不兼容問題。效果是以后使用時只用C類就好,此時C是類適配器。

對象適配器

假設(shè)A、B是兩個不兼容的接口,C為類,C實現(xiàn)了B接口,使用時需要將C實例化,C的對象負責(zé)向A提供其能夠接收的數(shù)據(jù),這個C的對象為對象適配器。有點像用電器和插座,你為了讓你的用電器能用上全世界的插座,你會買電壓轉(zhuǎn)換器。示例代碼如下:

interface A {
    showData();
}
interface B {
    int getCount();
    Object getData(int pos);
}

class C implements B{
    @override
    int getCount(){
        // 返回數(shù)據(jù)總數(shù)
        return dataSize;
    }
    @override
    Object getData(int pos){
        // 從列表中獲取相應(yīng)位置的數(shù)據(jù),這里是TopicData的對象
        return list.get(pos);
    }
}

// 該類是用來展示帖子
class Topic implements A{
    private B adapter;
    void setAdapter(B adapter){
        this.adapter = adapter;
    }

    @override
    void showData(){
        if(adapter == null){
            return;
        }
        allNum = adapter.getCount();
        // 根據(jù)總數(shù)產(chǎn)生相應(yīng)數(shù)量的顯示框
        ...
        for(i = 0;i < allNum; i++){
            // 將帖子的信息放入顯示框內(nèi)
            TopicData topicData = (TopicData) adapter.get(i);
            topicView.setData(topicData);    
        }
    }
}

總結(jié)

Singleon(單例)模式旨在利用機制控制類的實例化過程以及其對象的數(shù)量,同時能夠避免使用“全局變量”。Adapter(適配器)模式的目的是打通兩個接口間的交互,解決兼容性問題的同時,保證了交互雙方代碼的穩(wěn)定,同時該模式也能夠使得結(jié)構(gòu)上具有較大的靈活性。

謝謝您的觀看。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,545評論 19 139
  • 前言:設(shè)計模式之結(jié)構(gòu)型模式軟件模式與具體的應(yīng)用領(lǐng)域無關(guān),也就是說無論你從事的是移動應(yīng)用開發(fā)、桌面應(yīng)用開發(fā)、Web ...
    markfork閱讀 2,565評論 4 13
  • 我的筆記本電腦的工作電壓是20V,而我國的家庭用電是220V,如何讓20V的筆記本電腦能夠在220V的電壓下工作?...
    justCode_閱讀 1,501評論 0 5
  • 傻瓜。 只做你一輩子的傻瓜??,因為是你,所以愿意。
    月半HU閱讀 253評論 0 0
  • 曾經(jīng)的傷害,不堪的經(jīng)歷,身體的病痛,造成的痛苦,我們能做的,是接受并用心去感受當(dāng)下的感受,而不再是壓抑或排斥。它們...
    妹_清水閱讀 391評論 0 1

友情鏈接更多精彩內(nèi)容