zoukankan      html  css  js  c++  java
  • AS3中的单件(Singleton)模式

    单件(singleton)模式在c#中是最容易实现的模式,其主要用意就在于限制使用者用new来创建多个实例。但在as3中,构造函数必须是public的(语法本身要求的),而且也不能在构造函数中抛出异常(编译可通过,但是逻辑行不通),因为这样相当于把创建实例的路子完全切断了,一个实例也得不到!

    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com 

    错误代码:

     1 package{
     2     public class singleton{
     3          
     4         static private var _instance:singleton;
     5          
     6         public function singleton():void{
     7             throw Error("单件模式不能用new创建实例!");
     8         }
     9          
    10         public static function getInstance():singleton{
    11             if (_instance==null){
    12                 _instance = new singleton();//因为上面的构造函数抛出了异常,所以这里运行时会报错
    13             }
    14             return _instance;
    15         } 
    16              
    17     }
    18 }
    View Code

    怎样即能创建实例,又阻止使用者调用构造函数呢?这里要用到as3的一个特性:默认情况下,一个as文件,只能放一个类,而且必须用package声明,但有一种特殊情况:一个as文件中定义二个类,一个用package声明,一个不用!没有package的类,默认访问范围为“仅同在一个文件的类可访问”

     1 package
     2 {
     3  
     4     public class SingletonFactory
     5     {
     6         private static var _instance:Singleton2=null;
     7  
     8         public function SingletonFactory():void
     9         {
    10             trace Error("error!");
    11         }
    12  
    13         public static function getInstance():Singleton2
    14         {
    15             if (_instance == null)
    16             {
    17                 _instance=new Singleton2();
    18             }
    19             return _instance;
    20         }
    21     }
    22 }
    23  
    24 class Singleton2
    25 {
    26     import flash.utils.getTimer;
    27  
    28     private var _createTime:uint;
    29  
    30     public function Singleton2()
    31     {
    32         _createTime=getTimer();
    33     }
    34  
    35     public function toString():String
    36     {
    37         return "本实例的创建时间:" + _createTime.toString();
    38     }
    39  
    40     public function helloWorld(name:String):String
    41     {
    42         return "hello " + name + " !";
    43     }
    44 }

    测试:

     1 package
     2 {
     3     import flash.display.Sprite;
     4     import flash.utils.getTimer;
     5      
     6     public class main extends Sprite
     7     {
     8         public function main()
     9         {           
    10             var a:* = SingletonFactory.getInstance();
    11             trace(getTimer());
    12              
    13             var s1:* = SingletonFactory.getInstance();
    14             trace(s1.toString());
    15              
    16             //空循环,刻意占用cpu,消耗占时间而已
    17             for(var i:uint=0;i<999999;i++)
    18             {
    19                 //trace();
    20             }
    21              
    22             trace(getTimer());
    23             var s2:* = SingletonFactory.getInstance();
    24             trace(s2.toString());
    25              
    26             trace(s1==s2);
    27              
    28             trace(s1.helloWorld("jimmy"));
    29              
    30              
    31         }
    32     }
    33 }

    但这里有一个不爽的地方,SingleTon2类离开了文件SingletonFactory.as就无法访问了,所以我们在使用时,只能用var s1:* 来声明,虽然可以使用,但是在fd,fb等编程环境中却无法获得代码自动感知!

    可以借助接口改进一下:

    1 package
    2 {
    3     public interface ISingleton
    4     {
    5         function toString():String;
    6          
    7         function helloWorld(name:String):String;
    8     }
    9 }

    然后让SingleTon2实现该接口

     1 package
     2 {
     3  
     4     public class SingletonFactory
     5     {
     6         private static var _instance:Singleton2=null;
     7  
     8         public function SingletonFactory():void
     9         {
    10             trace Error("error!");
    11         }
    12  
    13         public static function getInstance():Singleton2
    14         {
    15             if (_instance == null)
    16             {
    17                 _instance=new Singleton2();
    18             }
    19             return _instance;
    20         }
    21     }
    22 }
    23  
    24 class Singleton2 implements ISingleton //这里改为实现接口
    25 {
    26     import flash.utils.getTimer;
    27  
    28     private var _createTime:uint;
    29  
    30     public function Singleton2()
    31     {
    32         _createTime=getTimer();
    33     }
    34  
    35     public function toString():String
    36     {
    37         return "本实例的创建时间:" + _createTime.toString();
    38     }
    39  
    40     public function helloWorld(name:String):String
    41     {
    42         return "hello " + name + " !";
    43     }
    44 }

    重新测试:

     1 package
     2 {
     3     import flash.display.Sprite;
     4  
     5     public class main extends Sprite
     6     {
     7         public function main()
     8         {
     9             var s:ISingleton=SingletonFactory.getInstance();
    10             trace(s.helloWorld("jimmy.yang"));
    11         }
    12     }
    13 }

    当然明白了上面的原理后,其实可以更一步简化,既然不声明package的类,只能限制在同一个文件内部的其它类可以访问,何不把它做为构造函数的参数?(这样不就限制了从外部调用构造函数么)

     1 package
     2 {
     3     public class Singleton2
     4     {
     5         private static var _instance:Singleton2;
     6          
     7         public function Singleton2(n:_nothing)
     8         {
     9                  
    10         }
    11          
    12         public static function getInstance():Singleton2{
    13             if (_instance==null){
    14                 _instance = new Singleton2(new _nothing());             
    15             }   
    16             return _instance;
    17         }
    18     }
    19 }
    20  
    21 class  _nothing{}

    这样就清爽多了,当然Singleton模式在AS3中的实现方法不止一种,下面这种也许更容易理解:

     1 package{
     2      
     3     public class Singleton{
     4          
     5         private static var _instance:Singleton = null;
     6          
     7         public function Singleton(){
     8             if(_instance == null){
     9                 _instance = this;
    10             }else{
    11                 throw Error("已经存在该类的实例!");
    12             }
    13         }
    14          
    15         public static function getInstance():Singleton{
    16             if(_instance != null){
    17                 return _instance;
    18             }
    19             return new Singleton();
    20         }       
    21          
    22     }
    23 }

    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com 
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    二叉树的遍历
    Balanced Binary Tree(平衡二叉树)
    Maximum Depth of Binary Tree(二叉树最大深度)
    Binary Tree Level Order Traversal(二叉树广度优先遍历或逐层遍历)
    解决mac下sublime中文乱码
    ubuntu下vi文本后出现不正常的情况
    Linux top命令的用法详细详解
    在Ubuntu 12.04下搭建Cocos2d-x 3.0 生成LuaBindings环境
    iOS7(Xcode5)中隐藏状态栏的方法
    VS2015 打包添加系统必备组件
  • 原文地址:https://www.cnblogs.com/buerjiongjiong/p/4730015.html
Copyright © 2011-2022 走看看