您好,欢迎来到我要学flash网!登录注册

【AS3与设计模式】 Singleton Pattern (单例模式)

来源:我要学flash网 | 作者:admin | 发表时间:2011-07-11 | 点击:  次

[arrow] 关于这一系列的索引页和说明请点这里 http://www.nshen.net/blog/article.asp?id=510

[arrow] 想直接下Singleton演示代码的点这里

Singleton Pattern(单例模式)应该是我最早学到的设计模式 ,因为它是最简单也是最常用到的 ,哪里都会遇到它。

先看一下定义:

The Singleton Pattern : ensures a class has only one instance, and provides a global point of access to it.

大概意思就是确保某个class只有一个实例,而且提供一个全局的访问点

从as1过来的我们喜欢把什么东西都往_root下或者_global下扔,然后在需要的时候直接访问_root.*** , _global.*** ,在面向对象的世界里这样做好像是不好的行为,也许可以考虑一下把这些东西放到一个singleton里。

测试代码:

首先创建一个叫做designpatterns的项目,主文件为designpatterns.as,以后的测试代码都在这个主文件里写

designpatterns.as :
 

  1. package {  
  2.  import flash.display.Sprite;  
  3.  import net.nshen.designpatterns.singleton.Singleton;  
  4.    
  5.  public class designpatterns extends Sprite  
  6.  {  
  7.  public function designpatterns()  
  8.  {  
  9.  
  10.  Test_Singleton()  
  11.    
  12.  }  
  13.    
  14.  public function Test_Singleton():void{  
  15.    
  16.  var s:Singleton=Singleton.getInstance()  
  17.  s.doSomething();  
  18.  /*  
  19.  使用构造函数创建实例会报错  
  20.  var s1:Singleton=new Singleton()  
  21.  s1.doSomething()  
  22.  */ 
  23.  }  
  24.  }  
  25. }  


Singleton类基本上有这三个特征

1. A private static property that holds the single instance of the class.
2. A public static method that provides access to the single instance if it's created and creates the single instance if it hasn't been created yet.
3. A way of restricting access to instantiating the class. This is usually achieved by making the constructor private. However, ActionScript 3.0 doesn't have private constructors. Later we'll examine an alternative way of restricting instantiation in ActionScript 3.0.

大概的意思就是

1 . 有一个 private static 属性引用类的唯一的实例
2 . 有一个 public static 方法来访问这个实例(如果实例已经被创建),或创建实例(如果实例还没被创建)
3 . 阻止用构造函数实例化这个类,这个一般使用私有的构造函数来实现,但由于AS3不支持private的构造函数,我们只能用其他的方法

Singleton类有很多种写法但都差不多,我们使用《 Advanced ActionScript 3 with Design Patterns 》这本书里的写法,稍加改动

Singleton 示意代码:
 

  1. package net.nshen.designpatterns.singleton  
  2. {  
  3.  public class Singleton  
  4.  {  
  5.  private static var _instance:Singleton;  
  6.  
  7.  public function Singleton(singletonEnforcer:SingletonEnforcer) {  
  8.  if(singletonEnforcer==null)throw new Error("singletonEnforcer"//这句是我后加的,原书里没有,这样是为了防止 new Singleton(null) 这种写法  
  9.  }  
  10.  
  11.  public static function getInstance():Singleton {  
  12.  if(Singleton._instance == null) {  
  13.  Singleton._instance = new Singleton(new SingletonEnforcer());  
  14.  }  
  15.  return Singleton._instance;  
  16.  }  
  17.  
  18.  public function doSomething():void {  
  19.  trace("SOMETHING!");  
  20.  }  
  21.  
  22.  }  
  23. }  
  24. class SingletonEnforcer {}  


这里使用了一个内部类 SingletonEnforcer ,在类外是无法访问的,所以巧妙的阻止了用new来创建,但还是能使用 new Singleton(null) 来创建,所以我又加了一句
if(singletonEnforcer==null)throw new Error("singletonEnforcer") 来阻止这种情况的发生

完整代码点此下载

=================理论与实践分割线=========================================================

实际应用中的Singleton:

RIAWAVE 是有多种设计模式的结合,现在主要看singleton部分----- ModelLocator

RIAWAVE是一个轻量化的Flex应用程序开发手法,更多介绍看
http://ria.richtechmedia.com/flexsample/sample.rar

ModelLocator主要任务就是 广播中心 ,储存中心 ,由于他是Singleton的任何时候都可以全局访问,所以非常适合做 ××中心,hoho~~

存储中心:

存的时候直接 ModelLocator.getInstance().xxx=xxx
取的时候直接 xxx =ModelLocator.getInstance().xxx

就像as1时代把东西都丢在_global或_root下一样方便

广播中心:

虽然在AS3中所有可视元件都可以广播事件了,但是如果每个元件都去广播事件,都不知道去监听谁的事件了,很容易乱套,所以出来了这个广播中心的概念。。广播中心的概念就是,所有人想广播就要使用广播中心广播,所有监听也直接监听广播中心就行了

由于ModelLocator是继承自EventDispatcher的可以广播事件,所以。。。。下面为riawave文档里的原话:

所有view、dao與其它物件要廣播時,統一都透過它的 dispatchEvent()執行;而所有需要知道(觀察)這個事件的物件,也統一透過它的 addEventListeners()來偵聽。

最常見的用途就是:

-當一個form要跟另一個form溝通時(例如 FormA 要傳一個值給 FormB),標準的做法是

FormA內:

ModelLocator.getInstance().dispatchEvent( new CustomEvent(“MyEvent”, dataObject));

FormB內:

ModelLocator.getInstance().addEventListener(“MyEvent”, onMyEvent);

Function onMyEvent( evt:CusomEvent ){

//handle the event

}

這樣做的好處有:

1、FormA 不會知道有 FormB 的存在,它只管拋出一個事件,內含要傳遞的資料

2、需要知道 MyEvent 的物件,自然會透過統一的廣播系統(ModelLocator)去偵聽這個事件然後處理,因此一個事件可以有許多個偵聽者,方便系統內不同部份協同處理

3、每個物件的封裝性不會被迫壞,不用像 ViewHelper一般必需要曝露元件內部的mehtod讓外界知道與操作,如此一來將來要重構元件或更改功能皆很方便,不用擔心會損壞其它部份。

其他实际运用的例子有待补充。。。。希望有实际例子的朋友跟我联系 nshen121(at)gmail.com

    顶一下
    (0)
    0%
    踩一下
    (0)
    0%
    本文引用地址:
      最新评论: 共有位网友发表了评论
      发表评论:
    请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
    评价:
    表情:
    用户名: 密码: 验证码: