2012-06-26 84 views
0

這是否可以很好地作爲動作腳本中的單例?即是否有任何我應該知道的陷阱,並且確實在這種情況下只會創建一個AVManager實例:一個非常簡單的Singleton?

請注意,我確實得到了預期的輸出(只有一次「實例化的第一次」和數字按照順序):

第一次實例化! 1

FILE 1:2

FILE 2:3

和最後4

下面是文件....

AV_CONFIG.as:

package { 
    public class AV_CONFIG { 
     public static var AVM:AVManager = new AVManager(); 
    } 
} 

AVManager.as:

package { 
    import flash.events.EventDispatcher; 

    public class AVManager extends EventDispatcher { 
     public var someConstantData:uint = 1; 

     public function AVManager() { 
      trace('instantiated first time!', someConstantData); 
     } 

    } 
} 

然後:

File1.as:

package { 
    import AV_CONFIG; 
    import flash.display.Sprite; 

    public class File1 extends Sprite { 

     public function File1() { 
      AV_CONFIG.AVM.someConstantData++ 
      trace('FILE 1:', AV_CONFIG.AVM.someConstantData); 
     } 

    } 
} 

File2.as:

package { 
    import AV_CONFIG; 
    import flash.display.Sprite; 

    public class File2 extends Sprite { 

     public function File2() { 
      AV_CONFIG.AVM.someConstantData++ 
      trace('FILE 2:', AV_CONFIG.AVM.someConstantData); 
     } 

    } 
} 

Main.as(中的DocumentClass):

package { 
    import AV_CONFIG; 
    import flash.display.Sprite; 

    public class Main extends Sprite { 

     public function Main() { 
      var f1:File1 = new File1(); 
      var f2:File2 = new File2(); 
      AV_CONFIG.AVM.someConstantData++ 
      trace('and finally', AV_CONFIG.AVM.someConstantData); 
     } 

    } 
} 

回答

7

一般用單身要:

  1. 限制或溶解創建類的實例的能力。
  2. 創建一種靜態獲取該類實例的方法。

例子:

public class AvManager 
{ 

    private static var _instance:AvManager; 
    internal static var created:Boolean = false; 

    public function AvManager() 
    { 
     if(AvManager.created) 
     { 
      throw new Error("Cannot created instances of AvManager, use AvManager.instance."); 
     } 

     AvManager.created = true; 
    } 

    public static function get instance():AvManager 
    { 
     if(_instance == null) 
     { 
      _instance = new AvManager(); 
     } 

     return _instance; 
    } 

    public function test():void 
    { 
     trace("Working."); 
    } 

} 

如果你現在可以使用:

AvManager.instance.test(); // Working. 
1

是啊這工作得很好,不同的方法是把一個AVManager就在自己的類文件的頂部:

public static function GetInstance():AVManager { 
    return AVM; 
} 

private static var AVM:AVManager = new AVManager(); 

,並得到它,像這樣的AVManager類的功能在需要時

此設置不是必需的,但通過禁止直接訪問提供了一些很好的小保護。

祝您的項目順利。

0

看到這個代碼,作爲創造一些不同的嘗試。

在AS3的其他Singleton

首先一個Interface

package test { 
public interface Foo { 

    function func0():void; 

    function func1(arg:String):String; 


} 
} 

然後一個Singleton

package test { 
public class BASIC_FOO { 
    public static const BASIC_FOO:Foo = new BasicFoo(); 
} 
} 

import test.Foo; 

class BasicFoo implements Foo { 

    public function func0():void { 
    } 

    public function func1(arg:String):String { 
     return arg; 
    } 
} 
+2

實現接口的Singleton的要點是什麼?沒有辦法提供替代實現,因爲客戶端正在程序上檢索特定的實例,而不是提供給他們。 –

+0

好的...那麼你可以用函數替換'const',否? – OXMO456

+0

他使用const來提供全局訪問,這是OOP的對立面,但我認爲const會比靜態函數調用更好地執行,如果您想要我真誠地評價哪種形式的氰化物可以做出最健康的早餐。 –

2

最大的疑難雜症是allowing global access to something if its state can be changed。如果這是一個項目,你希望代碼庫的維護時間超過一週左右,並且你認爲它可能有超過500行的代碼,我強烈建議避免這樣做 - 我可以從經驗告訴你在一個大型項目中,很難不可能找出數百個訪問您的Singleton的類中的哪一個改變了導致給定錯誤的狀態。

接下來,需求有一種改變的方法。如果你突然需要2臺AV管理員?你會發現你已經創建了這麼多的靜態引用,以至於改變它將會把整個項目搞得一團糟。再次,我從這裏講述經驗。如果你使用依賴注入(這只是一個可怕的方式,說需要一個AVManager的類有一個從外部填充的屬性),那麼這些類型的更改就變得簡單了......只需給他們一個不同的AVManager即可完成。最後,如果你有任何想要進行測試驅動開發的傾向,那麼以這種方式使用全局變量或靜態變量將會使所有代碼無法測試。你不能提供一個備用的AVManager進行測試,因爲所有依賴它的類都被硬連接去獲取特定的AVManager。

祝你好運!