Flex Singleton Pattern—-Flex中的单例模式

Categories: Flex; Tagged with: ; @ October 1st, 2008 0:49

1. 概述

Singleton Pattern的关键在于,只允许有一个对象存在.有时候我们需要有且只有一个对象存在,如播放器播放的歌曲, 购物车中的总额等.这些类对象只能有一个实例,如果制造出多个实例,就会导致很多问题.单例模式也给了我们一个全局的访问点,相对于全局变量来说, 单例模式采用的时lazy instantiaze,即在需要这个实例时才会创建.如果不需要这个实例,则永远不会产生.

1.1   Singleton Pattern中有一个 private static 实例,它引用类的唯一的实例
1.2  通过一个public static method 来提供该实例的全局访问点. [如果为空则新创建一个]
1.3  构造函数定义为Private或使用其他方法来阻止在外部使用new来创建实例

2. 分析

2.1 定义一个 Private static实例:private static var _instance:AppContext;
2.2 定一个Public static function 提供全局访问点:

public static function getInstance():AppContext {
if(!_instance) {
_instance = new AppContext(new PrivateClass);
}
return _instance;
}

2.3 相对与Java,Flex的构造函数必须为Public[因为ActionScript 3.0继承了当时的ECMAScript],而不能使用private,因此有可能通过new 来创建多个实例.
我们需要在构造函数为Public的时候防止在类外使用new创建类的实例.
OReilly.ActionScript.3.0.Design.Patterns中建议的方法:

在这种情况下,我们将构造函数参数中加入一个该类所在.as文件中的非主类[ActionScript 3.0 中一个as文件可以包含多个类,与文件名相同的类为主类,其他叫非主类,非主类只能在包内使用.]

class PrivateClass {
public function PrivateClass() {
trace(“Private Class set up”);
}
}

构造函数写为:

public function AppContext(pvt:PrivateClass) {
if(pvt == null) {
throw new Error(“不用允许使用new来创建AppContex,请示使用getInstance”);
}

}

但更为简洁的一个方法为:

public function AppContext() {
if(_instance != null) {
throw new Error(“Singleton!”);
}
}

3. 代码

  1. package com.insprise.notemanagement
  2. {
  3. publicclass AppContext
  4. {
  5. privatestatic var _instance:AppContext;
  6. private var _currentUser:int;
  7. public function AppContext() {
  8. if(_instance != null) {
  9. thrownew Error(“Singleton!”);
  10. }
  11. }
  12. publicstatic function getInstance():AppContext {
  13. if(_instance == null) {
  14. _instance = new AppContext();
  15. }
  16. return _instance;
  17. }
  18. public function get currentUser():int {
  19. return _currentUser;
  20. }
  21. public function set currentUser(currentUser_:int):void {
  22. _currentUser = currentUser_;
  23. }
  24. }//end of Class
  25. }//end fo package

4. 测试

两次通过getInstance创建实例,判断是否为同一个.使用该实例的 set currentUser方法,set currentUser,进一步确定两个实例是相同的.

  1. import com.insprise.notemanagement.AppContext;
  2. public function singletonTest():void {
  3. var firstSingleton:AppContext =  AppContext.getInstance();
  4. var secondeSingleton:AppContext = AppContext.getInstance();
  5. trace(firstSingleton == secondeSingleton);
  6. firstSingleton.currentUser = 10;
  7. trace(“Get firstSingleton.CurrentUser: “ + firstSingleton.currentUser);
  8. trace(“Get secondSingleton.CurrentUser: “ + secondeSingleton.currentUser);
  9. secondeSingleton.currentUser = 20;
  10. trace(“Get firstSingleton.CurrentUser: “ + firstSingleton.currentUser);
  11. trace(“Get secondSingleton.CurrentUser: “ + secondeSingleton.currentUser);
  12. }
		import com.insprise.notemanagement.AppContext;
		public function singletonTest():void {
			var firstSingleton:AppContext =  AppContext.getInstance();
			var secondeSingleton:AppContext = AppContext.getInstance();
			trace(firstSingleton == secondeSingleton);

			firstSingleton.currentUser = 10;
			trace("Get firstSingleton.CurrentUser: " + firstSingleton.currentUser);
			trace("Get secondSingleton.CurrentUser: " + secondeSingleton.currentUser);

			secondeSingleton.currentUser = 20;
			trace("Get firstSingleton.CurrentUser: " + firstSingleton.currentUser);
			trace("Get secondSingleton.CurrentUser: " + secondeSingleton.currentUser);
		}

测试结果:

Private Class set up

true

Get firstSingleton.CurrentUser: 10

Get secondSingleton.CurrentUser: 10

Get firstSingleton.CurrentUser: 20

Get secondSingleton.CurrentUser: 20

<->



// Proudly powered by Apache, PHP, MySQL, WordPress, Bootstrap, etc,.