ActionScript 3.0的單例模式(2009-12-21 10:17:24)
轉(zhuǎn):http://www./?p=154
一. Singleton的定義:確保某個(gè)class只有一個(gè)實(shí)例,,而且提供一個(gè)全局的訪問點(diǎn)
二.Singleton類基本上有這三個(gè)特征
大概的意思就是
1 . 有一個(gè) private static 屬性引用類的唯一的實(shí)例(Singleton Pattern中有一個(gè) private static 實(shí)例,它引用類的唯一的實(shí)例)
2 . 有一個(gè) public static 方法來訪問這個(gè)實(shí)例(如果實(shí)例已經(jīng)被創(chuàng)建),或創(chuàng)建實(shí)例(如果實(shí)例還沒被創(chuàng)建)(通過一個(gè)public static method 來提供該實(shí)例的全局訪問點(diǎn). [如果為空則新創(chuàng)建一個(gè)])
3 . 阻止用構(gòu)造函數(shù)實(shí)例化這個(gè)類,,這個(gè)一般使用私有的構(gòu)造函數(shù)來實(shí)現(xiàn),,但由于AS3不支持private的構(gòu)造函數(shù),,我們只能用其他的方法(構(gòu)造函數(shù)定義為Private或使用其他方法來阻止在外部使用new來創(chuàng)建實(shí)例)
三.Singleton詳解
Singleton Pattern的關(guān)鍵在于,只允許有一個(gè)對象存在.有時(shí)候我們需要有且只有一個(gè)對象存在,如播放器播放的歌曲, 購物車中的總額等.這些類對象只能有一個(gè)實(shí)例,如果制造出多個(gè)實(shí)例,就會(huì)導(dǎo)致很多問題.單例模式也給了我們一個(gè)全局的訪問點(diǎn),相對于全局變量來說, 單例模式采用的時(shí)lazy instantiaze,即在需要這個(gè)實(shí)例時(shí)才會(huì)創(chuàng)建.如果不需要這個(gè)實(shí)例,則永遠(yuǎn)不會(huì)產(chǎn)生.
在ActionScript 3.0里使用單例模式(Singleton Pattern),原來也可以如此的多姿多彩,!看了《Advanced ActionScript 3 with Design Patterns》一書后,,才發(fā)覺以前我所寫的單例模式并不是真正的單例模式,或者說是不完美的單例模式(至少在ActionScript 3.0里不應(yīng)該那樣寫),。所謂單例,,就是在整個(gè)應(yīng)用程序中有且只有一個(gè)類的實(shí)例,也就是說某個(gè)類只能被 new 一次。好文齊分享,,我把它轉(zhuǎn)述如下,,并收錄在我博客了(www.RIAHome.cn):
為了得到一個(gè)類的實(shí)例,你會(huì)使用 new 關(guān)鍵字,,然后加上類名,。這樣會(huì)調(diào)用類的構(gòu)造函數(shù)然后返回一個(gè)實(shí)例,就像這樣:
- var myObject:MyClass = new MyClass();
相信你已經(jīng)對這種實(shí)例化類的方式已經(jīng)非常熟悉,,但這種方法無法控制類的構(gòu)造,,所以我們準(zhǔn)備使用一個(gè)靜態(tài)方法:getInstance()。因?yàn)樗宦暶鳛殪o態(tài)(static),,所以它是屬于類而不是類的實(shí)例,,不通過類的實(shí)例來調(diào)用它而直接使用類名來調(diào)用它。就像這樣:
- public class MyClass {
- public function MyClass() {}
- public static function getInstance():MyClass {
- return new MyClass();
- }
- }
要得到類的實(shí)例,,我們就可以使用這個(gè)靜態(tài)的 getInstance() 方法:
- var myObject:MyClass = MyClass.getInstance();
防止類被實(shí)例化
只要能通過 getInstance() 方法得到實(shí)例,,那所有工作都已經(jīng)是按計(jì)劃進(jìn)行了。但,,我們注意到,,這樣始終不能防止他人通過 new 關(guān)鍵字來創(chuàng)建另一個(gè)實(shí)例。在一些語言里,,可以把構(gòu)造函數(shù)聲明為私有(只能包內(nèi)構(gòu)造),,這樣就可以解決這個(gè)問題(In other languages this problem would be solved by making the constructor private)。但在ActionScript 3.0里這是不被支持的,。
這樣的話,我們只能放一個(gè)大大的“public”關(guān)鍵字來聲明構(gòu)造函數(shù)為公有的,,然后寫上注釋告訴其他人:“這個(gè)類只能被實(shí)例化一次”,。那是不是就沒有其它方法來防止一個(gè)類被實(shí)例化呢?一切皆有可能,,方法當(dāng)然是有的,。我們可以利用面向?qū)ο蟮挠螒蛞?guī)則來達(dá)到目的,不正當(dāng)?shù)恼Z法是被禁止的,。
假如一個(gè)函數(shù)的參數(shù)沒有默認(rèn)值,,在沒有傳遞參數(shù)的情況下去調(diào)用這個(gè)函數(shù),編譯器就會(huì)報(bào)錯(cuò),。這是ActionScript 3.0的一個(gè)新特性,,這個(gè)特性同樣適用于構(gòu)造函數(shù)。ActionScript 3.0還有一個(gè)新特性,,在一個(gè)類文件里可以不只寫一個(gè)類,。也就是說在一個(gè) .as 文件里可以寫多個(gè)類。與文件名相同的那個(gè)類叫主類,,主類只能有一個(gè),,其它類可以是任意多個(gè),,而且其它類只對包內(nèi)可見,不能被外部引用,。就像這樣:
- package {
-
- public class MyClass {
-
- public function MyClass(enforcer:SingletonEnforcer) {}
-
- public static function getInstance():MyClass {
- return new MyClass(new SingletonEnforcer());
- }
-
- }
-
- }
-
- class SingletonEnforcer {}
現(xiàn)在你只能通過以下語句來創(chuàng)建類的實(shí)例,,因?yàn)槟悴豢赡茉谕獠客ㄟ^ new 關(guān)鍵字來創(chuàng)建只對包內(nèi)可見的 MyClass 類實(shí)例:
- var myInstance:MyClass = MyClass.getInstance();
注意:事實(shí)上,您還可以把 null 作為參數(shù)傳遞給構(gòu)造函數(shù)來 new 出一個(gè) MyClass 類實(shí)例,。每一種語言都不可能是完美的,,但以上做法在ActionScript 3.0里已經(jīng)能基本解決問題了。
直到現(xiàn)在為止,,你還不能創(chuàng)建單例,,當(dāng)你每次調(diào)用 getInstance() 方法時(shí),都會(huì)創(chuàng)建一個(gè)新實(shí)例,。下面我們將會(huì)了解到如何才能做到創(chuàng)建單例,。
實(shí)現(xiàn)單例與全局變量
我們需要怎樣做才能保證 MyClass 類只實(shí)例化一次?現(xiàn)在,,這個(gè) getInstance() 方法可以被無限次地調(diào)用,,然后無限次地 new 出很多個(gè) MyClass 類,這無異于使用一個(gè)普通的公有構(gòu)造函數(shù),。而我們只需要一個(gè) MyClass 類型的實(shí)例,,要這樣的話,我們應(yīng)該需要一個(gè)全局變量來保存這個(gè)唯一的實(shí)例,,然后每次調(diào)用 getInstance() 方法時(shí)返回這個(gè)實(shí)例而不是重新 new 一個(gè)出來,。就像這樣:
- package {
-
- public class MyClass {
-
- private static var _instance:MyClass; //定義一個(gè) Private static實(shí)例
-
- public function MyClass(enforcer:SingletonEnforcer) {}
-
- public static function getInstance():MyClass { //定一個(gè)Public static function 提供全局訪問點(diǎn)
- // 只有靜態(tài)的私有變量 _instance 為null時(shí)才new出一個(gè)MyClass,
- // 當(dāng)?shù)诙握{(diào)用這個(gè)靜態(tài)的 getInstance() 方法時(shí),,因?yàn)?_instance 不為null,,
- // 所以不再new出第二個(gè) MyClass,而是直接返回已存在的 _instance,。
- // 這樣就保證了全世界只有一個(gè) MyClass 類型的實(shí)例
- if(MyClass._instance == null) {
- MyClass._instance = new MyClass(new SingletonEnforcer());
- }
- return MyClass._instance;
- }
-
- }
- }
-
- class SingletonEnforcer {}
至此,,一個(gè)單例模式就擺在眼前了。這不是翻譯原文,,跟原文已經(jīng)不同了,,所以有什么說得不當(dāng)請指出來,也希望通過這篇文章,,您會(huì)對ActionScript 3.0里的單例模式有所認(rèn)識(shí),。