Luar's Flash Playground:從Global Variable的創建看AS2繼承Static Class的弱點與及Singleton的濫用
新聞(100)
觀點或評論(93)
Flash書(63)
教程(65)
Design Patterns(3)
FlashCom筆記(45)
Flash Remoting筆記(27)
Flex筆記(11)
Flash Lite筆記(14)
PHP資訊(22)
Ajax筆記(9)
習作(46)
組件(15)
酷站(31)
學習資源(28)
書籍推介(15)
本站與我(90)
RSS瀏覽器
聯絡
熱愛鑽研
Ajax
ActionScript
Flash
Flash Lite
Flex
Flash Remoting
FlashCom
Director
Lingo
PHP
Multiplayer Game

搜尋
VCASMO
從Global Variable的創建看AS2繼承Static Class的弱點與及Singleton的濫用 (23-10-2004)

在一個應用中,某Object(指Data Type)只可以有一個,即一個Global Variable給所有人共用,有以下三種可行做法:

_global

_global.luar = {age:12, gender:"M"};
這做法最簡單,在AS1經常這樣用,不過有以下缺點:
  • 不適合用於AS2,因為讀取外部東西,會破壞Object封裝性。
  • 因為數值是共用,當人人都修改過它後,要重設(Reset),怎麼辦?難道定義另一個global數值,不准別人修改?
  • 當用另一個global數值進行Reset時,例如:
    luar = luarDefault;
    這不是Object Clone,只是一個Reference指定,當別人修改luar時,等於連luarDefault都被修改了,以後永遠無法Reset。[下載範例]
  • 可以編寫一個函數,逐一屬性複製:[下載範例]
    function objReset() {
        for (var i in luar) {
            luar[i] = luarDefault[i];
        }
    }

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類,會有一連串問題:

  • SingleObjectChild.屬性是undefined,因為Flash編譯器有Bug,如果FLA沒有引用過SingleObject類,它是不會包含在SWF裡,
  • 只有用AS1的原型鏈去實現:[下載範例]
    class SingleObjectChild extends SingleObject {
        static var __proto__ = SingleObject;
    }
    當執行範例SingleObject_4.fla,SingleObjectChild.reset()根本沒有重設SingleObjectChild屬性,換句話說,子類雖然得到了父類屬性和Method,可是Method的Scope仍然在父類裡,暈。
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上有錯誤的依賴關係。

其他參考資料

本文章由luar發表。
意見
  • Great!

    jackyshe於24-10-2004發表

  • luar:
    您好, 我非常想购买您的《AS2与RIA》一书..但是我身处深陆,在香港那边也没有亲戚朋友..多次与那边的电脑书店联系,他们都认为买一本书,他都难跑邮局打包裹呢..没办法之下,经过朋友介绍认识一个在香港那边的朋友,他答应我可以买到,我经过银行汇款给他后,到现在为止他没有任何音讯了,我想我是被骗了吧。。。555,对于我,一个内陆高三的学生,这是半月的伙食费啊...
    在这里我想能不能直接与您联系购买得一本.希望您能帮帮我..

    QQ:7462792
    MSN:xzskyweb@hotmail.com

    oydj於25-10-2004發表

  • 其实anti-pattern也有很多不错的地方值得学习。可惜我算是废了,连看技术研究的书籍时间都没有了。

    7yue於26-10-2004發表

  • 其實看了您的第二本書,對於單例覺得相當好用。
    剛看了最後那幾句話我不是很清楚,(應該放在描述他們的instance裡面。)不知能否解釋清楚一點,謝謝!!

    kevin63jj於24-11-2004發表

同組文章

Movable Type 3.15系統支持,Luar's Production版權所有。