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 {}
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 {}
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()来调用。
(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
相关文章推荐
- Singleton Pattern (单例or单件模式)的几种实现方式
- PHP实现单件模式的几种方式
- 设计模式-PHP实现单件模式的几种方式
- 设计模式-PHP实现单件模式的几种方式
- 设计模式-PHP实现单件模式的几种方式
- PHP实现单件模式的几种方式
- 单例模式的几种实现方式
- 单例模式singleton的几种实现方式
- 谈谈下订单的几种实现方式(用不同的模式实现:装饰器模式、代理模式、命令模式、状态模式、模版模式)
- JAVA设计模式---单例模式的几种实现方式比较
- 结合Android源码分析总结单例模式的几种实现方式
- 单例模式的几种实现方式总结
- 订单的几种实现方式(用不同的模式实现:装饰器模式、代理模式、命令模式、状态模式、模版模式)
- [读书笔记] 单例模式的几种实现方式
- 单例模式的几种实现方式
- 设计模式之单例模式简介与几种实现方式
- 单例模式的几种实现方式
- 设计模式用过哪些,应用场景是什么;单例模式有几种实现方式,代码怎么写?
- 单例模式的几种实现方式和各自优缺点分析
- Python中的单例模式的几种实现方式的及优化