您的位置:首页 > 其它

singleton pattern(单件模式)的几种实现方式

2008-12-29 14:20 621 查看
由于AS3.0本身不支持private/protected 构造器,所以实现一个singleton pattern很麻烦,必须采用曲线救国的方式。下面先列出几种实现方式,这几种方式都有一些漏洞。
(1)
// faulty example
package {
    public class Singleton {
        private static var singleton : Singleton;
        
        public static function getInstance() : Singleton {
            if ( singleton == null )
                singleton = new Singleton( arguments.callee );
            return singleton;
        }
       
        //NOTE: AS3 does not allow for private or protected constructors
        public function Singleton( caller : Function = null ) { 
            if( caller != Singleton.getInstance )
                throw new Error ("Singleton is a singleton class, use getInstance() instead");
            if ( Singleton.singleton != null )
                throw new Error( "Only one Singleton instance should be instantiated" );    
            //put instantiation code here
        }
    }
}

因为构造器只检测caller是否等于Singleton.getInstance,来确保它只被实例化一次,这样传一个同样的参数进去来饶过检查,就不能保证实例化次数。如下:
var a:Singleton = new Singleton(Singleton.getInstance);
var b:Singleton = new Singleton(Singleton.getInstance);
// a !== b
(2)
// faulty example
package whatever {
  public class MySingleton {
    public function MySingleton(singletonEnforcer:MySingletonEnforcer) { }

private static var instance:MySingleton;

pubic function getInstance():MySingleton {
if (instance == null)
instance = new MySingleton(new MySingletonEnforcer());
return instance;
}
}
}

//this is in MySingleton.as but is outside the package block
class MySingletonEnforcer {}
这个办法也是《design pattern》列出的标准做法,通过传递package外的内部class,来确保
实例化的个数。作者提到这样不能避免别人传递null参数来绕开。如下:
var a:MySingleton = new MySingleton(null);
var b:MySingleton = new MySingleton(null);

// a !== b
如果在构造器裏加入检测传参是否是null的判断,就可以避免了。
package whatever {
  public final class MySingleton {
    public function MySingleton(singletonEnforcer:MySingletonEnforcer) {
        if (singletonEnforcer == null) {
            throw new Error ("MySingleton is a singleton class, use getInstance() instead");            
        }
    }

private static var instance:MySingleton;

public static function getInstance():MySingleton {
if (instance == null)
instance = new MySingleton(new MySingletonEnforcer());
return instance;
}
}
}

//this is in MySingleton.as but is outside the package block
class MySingletonEnforcer {}

例子1也可以用下面的方法完善:
package {
    public final class Singleton {
        private static var singleton : Singleton;
        
        public static function getInstance() : Singleton {
            if ( singleton == null )
                singleton = new Singleton( hidden );
            return singleton;
        }
        private static function hidden():void {}       
        //NOTE: AS3 does not allow for private or protected constructors
        public function Singleton( caller : Function = null ) { 
            if( caller != hidden )
                throw new Error ("Singleton is a singleton class, use getInstance() instead");
            if ( Singleton.singleton != null )
                throw new Error( "Only one Singleton instance should be instantiated" );    
            //put instantiation code here
        }
    }
}

下面给出最简介的一种办法来实现:
package {

        public final class Singleton {

                private static var instance:Singleton = new Singleton();

public function Singleton() {
if( instance ) throw new Error( "Singleton and can only be accessed through Singleton.getInstance()" );
}
public static function getInstance():Singleton {
return instance;
}
}
}
这样做的妙处就在该单件类在被引用的时候,VM初始化过程中,静态变量为null而在构造器裏的检测
并没有被触发,所以无法使用new()/ new(***)的办法来实例化,只能通过getInstance()来调用。
来源:http://life.neophi.com/danielr/2006/10/singleton_pattern_in_as3.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  null function class