在一個應用中,某Object(指Data Type)只可以有一個,即一個Global Variable給所有人共用,有以下三種可行做法:
_global _global.luar = {age:12, gender:"M"}; 這做法最簡單,在AS1經常這樣用,不過有以下缺點:Static Class
建立一個Class,將屬性設定為Static,並加入Reset()方法:
class SingleObject {
private static var ageDefault:Number = 12;
private static var genderDefault:String = "M";
public static var age:Number = ageDefault;
public static var gender:String = genderDefault;
private function SingleObject() {}
public static function reset() {
age = ageDefault;
gender = genderDefault;
}
} 為了避免Class被創建多個Instance,特別將Constructor變成Private,無法使用new。[下載範例]
不過如果有另一個SingleObjectChild類繼承SingleObject類,會有一連串問題: Singleton
Singleton(單例模式)保證Class只有一個Instance:[下載範例] class SingletonObject {
private static var me:SingletonObject;
private var ageDefault:Number = 12;
private var genderDefault:String = "M";
public var age:Number = ageDefault;
public var gender:String = genderDefault;
private function SingletonObject() {
}
public static function getInstance():SingletonObject {
if (me == null) {
me = new SingletonObject();
}
return me;
}
public function reset() {
age = ageDefault;
gender = genderDefault;
}
}
當執行範例SingleObject_5.fla,雖然定義2個類似Instance的Variable,但他們其實指向單一個SingletonObject Instance,所以當屬性改變時,所有人都是共用著SingletonObject Instance,因此他們裡面的數值都會改變。
如果繼承SingletonObject類:[下載範例] class SingletonObjectChild extends SingletonObject {
static var __proto__ = SingletonObject;
} 當執行範例SingleObject_6a和6b.fla,雖然定義2個Variables是分別向父類和子類取得Instances.但其中一個改變屬性數值,所有人都會受影響。子類reset()也能夠順利重設屬性。但是定義一個子類出來,跟父類共享屬性,實在是有點荒謬(AS2中,Private成員不是真正Private,子類可以使用父類Private成員,即等於Java中Protected成員)。Java中實現Singleton的Private Constructor,使Singleton無法繼承,AS2可惜AS2中容易墜入這種陷阱中,繼承Singleton,跟Singleton原意背道而馳,是一種濫用。
Singleton另一個陷阱,由於Singleton在Design Pattern好像比較簡單易理解,初學時就會出現什麼都用Singleton的情況,其實在這個Global Variable的探討中,利用Singleton去實現,都是一種Anti-Pattern,因為只有設計不當的應用,才需要一個Global Variable,這些Variables應該是放在他們所描述的Instances對應Classes裡,不是將他們抽出來,放在一個不相干的Singleton類裡,使這些Variables在OOD上有錯誤的依賴關係。
其他參考資料: |