[转]关于单例与多例模式的调整

[url]http://sban.biz/469[/url]

15.1 旧单例模式的实现

在之前的fllib中,单例与多例模式的对象实例是存储在Object之内的,为便于下一步说明问题,现摘录一段旧单例模式的实现代码于此:
protected static var instances :Object = {};

/**
*
* 取出一个单例对象,如果没有,则新建并返回
* 使用该模式工具的类的构造器必须无参或有默认参数
*
* 示例:
* protected var userModel() = Singleton.retrieve(Model_User) as Model_User;
* 所有UserModel的单例名称纺定为同一个名称
*
* @param c 类定义
* @return 单例对象
*
*/
public static function retrieve(c :Class) : Object
{
return (instances[getQualifiedClassName(c)] ||= new c);
}

/**
* 从缓存中移除不再使用的单例对象,使得GC可以回收其内存
* @param instanceOrClass 单例对象或类定义
*
*/
public static function remove(instanceOrClass : *) :void
{
delete instances[getQualifiedClassName(instanceOrClass)];
}
如果单例对象的实例不存在,则新建、存储并返回,这个过程仅用一行代码实现了,在目前的AS3语言框架内,笔者很难找出比它更简洁的代码了(莫说笔者自恋,如果读者能够找出更简洁的实现,请告诉我)。
15.2 新单例模式的实现

但是笔者把它改掉了,新的单例模式仅是一个代码示例,如下:
public final class Singleton
{
public static function getInstance() :Singleton
{
return (instance ||= new Singleton);
}

protected static var instance :Singleton;
}
我为什么要做这样的修改?原因有三:
1)“用最简单的方法实现最基本的功能”以及“类库在提供帮助的同时,应当竭力减少对使用者的束缚”是fllib的核心架构思想之二,新的单例模式的实现更加符合这两个思想。
2)把实现存储在Object之内,不便于追踪调试。
3)最主要的原因,缘于flash player的垃圾内存回收机制。如果一个对象在当前程序域内已经没有任何引用,则它可以被回收。在旧的单例模式内,很多单例对象存储在Object之内,如果外界对这些实现对象均无引用了,此时单例模式的instances变量便成为内存海洋中的一片孤岛,随时都有可能被GC回收,回收之后单例对象将再新建,已有的数据全部丢失。这也是业界有识之士摒弃单例模式的主要原因之一。
15.3 另一种基于Dictionary的实现

Dictionary相比Object,仅是在构造器内多了一个weakKeys参数。官方对这个参数的说明如下:
参数

weakKeys:Boolean (default = false) — 指示 Dictionary 对象在对象键上使用“弱”引用。 如果对某个对象的唯一引用位于指定的 Dictionary 对象中,则键符合垃圾回收的条件,并且在回收对象时会被从表中删除。
如果一个对象的唯一引用位于Dictionary中,并且weakKeys参数是true,那么该对象便会被GC回收,反之则不会。这也是Dictionary相比于Object唯一的有用之处,不然Adobe团队不可能提供两个完全一模一样的类。
另一个基于Dictionary的单例模式实现:
protected static var instances :Dictionary = new Dictionary(false)
public static function retrieve(c :Class) : Object
{
return (instances[getQualifiedClassName(c)] ||= new c);
}
public static function remove(instanceOrClass : *) :void
{
delete instances[getQualifiedClassName(instanceOrClass)];
}
不同之处,仅是instances变量的类型注释由Object改为了Dictionary。
读者在行码的时候须注意,如果一昧使用Object,则可能造成莫名其妙的数据丢失;如果一昧的的使用Dictionary(并且weakKeys默认为false),则可能造成很多许多对象不能被GC及时回收,内存占用高居不下。用什么,怎么用,须区别对待。
笔者不使用Dictionary实现单例模式,另有原因,见上所述。
15.4 源码

多例模式:Multiton.as
单例模式:Singleton.as
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值