javascript设计模式交流(一) ——Singleton Pattern

转载 2012年03月27日 11:38:49


原文出处:http://bbs.51js.com/thread-43775-1-1.html


即使是简单的脚本语言,应用良好的模式可以得到非常“优美”的代码和较高的效率。
尤其是对于交互要求较高的B/S系统,非常有必要用设计模式来优化代码。

单件模式(Singleton Pattern)是一种非常基本和重要的创建型模式。
“单件”的职责是保证一个类有且只有一个实例,并提供一个访问它的全局访问点。
在程序设计过程中,有很多情况下需要确保一个类只能有一个实例。

传统的编程语言中为了使一个类只有一个实例,最容易的方法是在类中嵌入静态变量,并在第一个实例中设置该变量,而且每次进入构造函数都要做检查,不管类有多少个实例,静态变量只能有一个实例。为了防止类被多次初始化,要把构造函数声明为私有的,这样只能在静态方法里创建一个实例。

在javascript中,虽然我们仍然可以指定静态方法来构造对象,但由于我们不能利用构造函数的“私有”来禁止多个实例的生成,因此要完全实现Singleton并没有想象中那么简单。

请看下面的例子:

  1. <script>
  2. function SingletonObject()
  3. {
  4.         SingletonObject.prototype.methodA = function()
  5.         {
  6.                 alert('methodA');
  7.         }
  8.         SingletonObject.prototype.methodB = function()
  9.         {
  10.                 alert('methodB');
  11.         }
  12.         SingletonObject.instance = this;
  13. }
  14. SingletonFactory = new Object();
  15. SingletonFactory.getInstance = function()
  16. {
  17.         if(SingletonObject.instance == null)
  18.                 return new SingletonObject();
  19.         else
  20.                 return SingletonObject.instance;
  21. }

  22. var instA = SingletonFactory.getInstance();
  23. var instB = SingletonFactory.getInstance();
  24. instA.methodA();
  25. instB.methodA();
  26. alert(instA == instB); //成功
  27. var instC = new SingletonObject();
  28. instC.methodA();
  29. alert(instA == instC); //失败
  30. </script>
复制代码运行代码另存代码

上面的例子试图通过传统的方式来实现Singleton模式,而通过调用SingletonTest.getInstance()来获得对象确实可以保证“唯一实例”,然而,这个例子的失败之处在于它并没有有效地禁止Singleton对象的构造,因此如果我们在程序代码中人工加入new SingletonObject(),仍然可以获得到多个对象而导致模式失败。

一个改进的替代方案如下:
  1. <script>
  2. function SingletonObject()
  3. {
  4.         if(SingletonObject.instance != null)
  5.         {
  6.                 alert("不能创建多个singleton实例!");
  7.                 throw new Error();
  8.         }
  9.         SingletonObject.prototype.methodA = function()
  10.         {
  11.                 alert('methodA');
  12.         }
  13.         SingletonObject.prototype.methodB = function()
  14.         {
  15.                 alert('methodB');
  16.         }
  17.         SingletonObject.instance = this;
  18. }
  19. SingletonFactory = new Object();
  20. SingletonFactory.getInstance = function()
  21. {
  22.         if(SingletonObject.instance == null)
  23.                 return new SingletonObject();
  24.         else
  25.                 return SingletonObject.instance;
  26. }

  27. var instA = SingletonFactory.getInstance();
  28. var instB = SingletonFactory.getInstance();
  29. instA.methodA();
  30. instB.methodA();
  31. alert(instA == instB); //成功
  32. try
  33. {var instC = new SingletonObject(); }//抛出异常
  34. catch(e)
  35. {alert('系统成功抛出了异常,阻止了instC的构造!');}
  36. </script>
复制代码运行代码另存代码

这样当用户试图自己创建多个对象的时候,通过人工抛出异常来阻止。不过这么做还是有一点点违反了"初衷",即没有满足“必须通过静态方法来构造唯一实例”这个基本条件。因为用户可以在最开始的时候还是可以采用new操作符来构造对象,比如在一开始写var instA = new SingletonObject()来构造instA并不会导致抛出异常,这不能不说是这种方法的一个缺陷。

于是我们进一步思考,得到了下面第三种方法,这种方法巧妙利用了“匿名”函数的特征来禁止对SingletonObject类构造函数的访问,可以说比较好的模拟了私有构造函数的特性,从而比较完美地解决了用javascript实现Singleton Pattern的问题。

  1. <script>
  2. (function(){
  3.         //instance declared
  4.         //SingletonFactory Interface
  5.         SingletonFactory = {
  6.                 getInstance : getInstance
  7.         }

  8.         //private classes
  9.         function SingletonObject()
  10.         {
  11.                 SingletonObject.prototype.methodA = function()
  12.                 {
  13.                         alert('methodA');
  14.                 }
  15.                 SingletonObject.prototype.methodB = function()
  16.                 {
  17.                         alert('methodB');
  18.                 }
  19.                 SingletonObject.instance = this;
  20.         }
  21.         
  22.         //SingletonFactory implementions
  23.         function getInstance()
  24.         {
  25.                 if(SingletonObject.instance == null)
  26.                         return new SingletonObject();
  27.                         
  28.                 else
  29.                         return SingletonObject.instance;
  30.         }

  31. })();

  32. var instA = null;
  33. try
  34. {
  35. alert("试图通过new SingletonObject()构造实例!");
  36. instA = new SingletonObject();
  37. }
  38. catch(e){alert("SingletonObject构造函数不能从外部访问,系统抛出了异常!");}

  39. instA = SingletonFactory.getInstance();  //通过Factory上定义的静态方法获得
  40. var instB = SingletonFactory.getInstance();
  41. instA.methodA();
  42. instB.methodA();

  43. alert(instA == instB); //成功

  44. var instC = null;
  45. try
  46. {
  47. alert("试图通过new SingletonObject()构造实例!");
  48. instC = new SingletonObject();
  49. }
  50. catch(e){alert("SingletonObject构造函数不能从外部访问,系统抛出了异常!");}
  51. </script>
复制代码运行代码另存代码

相关文章推荐

Web前端开发JavaScript设计模式 -- 单体模式(The Singleton Pattern)

前言 在Web前端项目的开发中,争取做到编写代码的结构清晰、易读、易维护、安全等方面的重要性是不言而喻的。为了更好地进行代码编写,借鉴设计模式中的相关编程思想是比较有帮助的,下面会陆续介绍一些简单易...

【一】设计模式——单例模式(Singleton Pattern)

设计模式——单例模式 简单快捷的了解设计模式
  • yk3372
  • yk3372
  • 2016年11月26日 17:04
  • 223

Head First 设计模式——单件模式(Singleton Pattern)

单件模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点 单件模式确保程序中一个类最多只有一个实例。我们在程序中会遇到这种情况如:线程池,缓存,对话框,...

设计模式——单例模式(Singleton Pattern)

设计模式——单例模式(Singleton Pattern) 单例设计模式总结 多线程中的单例

您的设计模式——单例模式【Singleton Pattern 】

这个模式是很有意思,而且比较简单,但是我还是要说因为它使用的是如此的广泛,如此的有人缘, 单例就是单一、独苗的意思,那什么是独一份呢?你的思维是独一份,除此之外还有什么不能山寨的呢? 我们举个比较...

设计模式——单件模式(Singleton Pattern)

一、单件模式定义及经典实现 确保一个类只有一个实例,并提供一个全局访问点。 单例的经典(简单)实现如下:public class Singleton{ // 利用静态变量记录Singlet...

设计模式(1)——单例模式(Singleton Pattern)

单例模式,可以说是GOF的23种设计模式中最简单的一个。 这个模式相对于其他几个模式比较独立,它只负责控制自己的实例化数量单一(而不是考虑为用户产生什么样的实例),很有意思,是一个感觉上很干净的模式...

深入浅出设计模式(1)——单件模式(Singleton Pattern)

1          模式简介 singleton是设计模式家族中的小弟弟,重量轻,没有复杂的经历,很单纯,所以叫单件(just a joke)。因为简单,容易被人洞悉,所以经常被人唤来唤去,sin...

java设计模式——单例模式(Singleton Pattern)

定义:         单例模式(Singleton Pattern):单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。 单例模式是一...

设计模式——单例模式(Singleton Pattern)

单利模式的意图是确保一个类只有一个实例,并提供一个全局的访问点
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:javascript设计模式交流(一) ——Singleton Pattern
举报原因:
原因补充:

(最多只允许输入30个字)