如何讓很多activity共用一個物件 獨體模式(Singleton Pattern)

如何讓很多activity共用一個物件 獨體模式(Singleton Pattern)

情境

假設我們有一個物件,要如何把它從目前的activity丟到另外一個activity,
上網查,找到了一個設計模式叫做 Singleton 真的超好用的,

程式碼說明

簡單說明一下

假設有一個類別, 在目前的Activity裡面設定好狀態了,
但是你又想讓這個類別保留著, 然後到另外一個Activity裡面拿出來用,
這時候你該怎麼辦呢? 這時候你會想到靜態類別, 但是你要如何能夠保證,
你生出來的類別,不會被濫用呢?
這時候Singleton就是一個好方法。
它可以讓你只產生一個物件。
假設你有一個類別 叫做Singleton長這樣

class Singleton{
    public Singleton(){}
}

那你想要建立這個類別的物件
你可能會這樣做

Singleton single = new Singleton();

但是如果你要讓別人沒辦法自由的建立這個類別的物件
你可以這樣做

class Singleton{
    private Singleton(){}
}

那這樣誰能夠存取?
當然只剩下自己能夠存取囉!
所以接下來你可以這樣寫,

class Singleton{
    private static Singleton single;
    private Singleton(){}
    public static Singleton getInstance(){    
        single = new Singleton();
    }
    return single;
}

如此一來, 只要呼叫Singleton.getInstance()就可以產生一個物件了。

可是這樣又不太對, 如果每個人都一直呼叫A.getInstance();
不就還是建立一堆物件, 所以加上幾行限制

class Singleton{

    private static Singleton single;
    private Singleton(){}
    public static Singleton getInstance(){
        if(single == null){
            single = new Singleton();    
        }
        return single;
    }
}

這樣一來, 就只能產生一個物件, 可是這時候卻又出現了一個問題,
假設有兩個執行緒同時存取這個類別的getInstance這個方法,
如果我們的直行順序變成這樣:

A 執行緒 跑到了 第五行 時間到了
B 執行緒 跑到了 第五行 時間到了
A 執行緒 在第六行 建立一個物件。
B 執行緒 在第六行 建立一個物件。

違反 Singleton的原則 : 只建立一個物件。

所以我們只需要將getInstance() 變成一個同步化的方法, 就可以將上面的問題解決掉了。

class Singleton{
    private static Singleton single;
    private Singleton(){}
    public static synchronized Singleton getInstance(){    
        if(single == null){    
            single = new Singleton();
        }
        return single;
    }
}

ya, 解決了。
並沒有。

synchronized是很耗效能的, 如果大量的呼叫這個方法, 你的電腦會有一群耗能執行緒再折磨你的電腦,而且這些並沒有意義, 其實如果第一次完成new以後, 根本不需要再對getInstance做同步了。

所以又開發了一個想法, 那如果我們一開始程式就幫你把物件new好了呢?

class Singleton{
    private static Singleton single = new Singleton();
    private Singleton(){}
    public static Singleton getInstance(){     
        return single;
    }
}

這樣一來, 雖然少了Lazy Initialization(延遲出屎化初始化:需要用到物件的時候才建立),
如果你的類別不是吃很大的資源,其實這樣就很夠用了。

那我們回到原本的題目: 如何讓一個物件在很多個activity穿梭呢?

假設你寫了一個貓類別

class Cat{
    private static Cat candy = new Cat();
    private Cat(){}
    public static Cat getMyCat(){
        return candy;
    }
    //其他方法
}

然後在A activity

public class A extends Activity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Cat candy = Cat.getMyCat();
        //作一些設定

        Intent i = new Intent();
        i.setClass(A.this, B.class);
        startActivity(i);//跳到B頁面
    }
}

然後在B activity display

public class B extends Activity{
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);    
        Cat candy = Cat.getMyCat();
        //取得一些資訊
        //display
    }
}

這樣表示無論你在哪裡就可以存取Cat類別的物件,
也等同於,把某個物件傳到另外一個Activity。