`
步行者
  • 浏览: 167719 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

为什么需要Singleton

阅读更多

为什么需要 单例设计模式(Singleton)?

像下面的一个单例

 

public class Singleton {
	private static Singleton instance = null;
	private Singleton(){};
	public static synchronized Singleton getInstance(){
		if(instance == null)
			instance = new Singleton();
		return instance;
	}
	public void doSomething(){
		//do something
	}
}


它要实现的主要目标,就是在一个应用中只维护一个Singleton实例

但一个类在一个应用中也是唯一的,为什么不能直接以类作为单例呢?

 

public final class AnotherSingleton{
	private AnotherSingleton(){}
	public static synchronized void doSomething(){
		//do something
	}
}

 

把类的所有方法都改为静态方法,

所有属性都改为静态属性(我们可以把

静态属性看成类的内部状态),

但是不允许实例化,

对类的操作相当于对单例的操作

而且类也可以维护内部状态(通过静态私有属性)

这完全满足了单例的要求。

不知道为什么需要单例模式。。。


因为我想不出来在什么情况下 单例可以满足需求

而 类 不能。

 

 

 

分享到:
评论
46 楼 Saito 2009-06-08  
步行者 写道
Saito 写道
这个东西涉及到 Singleton 跟 MonoState .

   前段时间我们也讨论过. 不过像Math这种工具类. 它实际没有存在对象的必要. 这时就没有必要单例.
   并且大量的static的方法. 实际上是一种面向对象的倒退.

   我们可以写一个Gui程序. 在菜单用Singleton . 能把它写成纯 static的嘛? 我觉得使他丧失了很多东西. 不值得...


注意我前面的 AnotherSingleton 的构造函数是私有的
而 MonoState 的的构造函数是共有的

MonoState 和 Singleton 看起来很相似
但他们体现了不同的设计动机
MonoState 可以被大量实例化 (被实例化的对象 享有共同的 类状态),
而 Singleton 就 只有一个 (它体现的是 全局的应用状态 )


   你的AnotherSingleton无论私有或共有. 实际上是没有任何意义的.

   既然他们是相同的. 那你去实例化多个有什么意义.  唯一的好处是给别人提醒一下. 别浪费. 但是一般看了api的人应该都不会那么傻. .

   就跟你见过有人有事没事就实例化几个Math么?

   全局的应用状态. 一般这样来说. 对象是可以保存状态的. 而Math这种东西一般没有状态. 这也是Singleton跟Monostate的最根本区别.  Singleton我是用来用他那个instance的. 而Monostate.我用的只是那个class.  .
45 楼 步行者 2009-06-08  
hatedance 写道
忘掉模式吧。单例的目的只是体现设计者的思路而已。设计师只是想说:这个类在这个系统里应该只有一个实例。就像一把防君子不防小人的锁,后人要hack也是可以的。

仅此而已。不必拘泥。


“忘掉模式吧。”
呵呵 , 这句话听着太耳熟
“忘掉模式吧。”实际上是对滥用模式的一种感慨,
应该说“不要刻意追究模式”

模式不是一个类应该有几个实例的问题,我们不玩代码魔术

模式不是一把锁,而是一条路,后人可以走这条路,
也可以另觅蹊径 。
44 楼 linzy410 2009-06-08  
在getInstance()需要做init()的时候,改成静态方法就无法做到
43 楼 hatedance 2009-06-08  
忘掉模式吧。单例的目的只是体现设计者的思路而已。设计师只是想说:这个类在这个系统里应该只有一个实例。就像一把防君子不防小人的锁,后人要hack也是可以的。

仅此而已。不必拘泥。
42 楼 步行者 2009-06-08  
Saito 写道
这个东西涉及到 Singleton 跟 MonoState .

   前段时间我们也讨论过. 不过像Math这种工具类. 它实际没有存在对象的必要. 这时就没有必要单例.
   并且大量的static的方法. 实际上是一种面向对象的倒退.

   我们可以写一个Gui程序. 在菜单用Singleton . 能把它写成纯 static的嘛? 我觉得使他丧失了很多东西. 不值得...


注意我前面的 AnotherSingleton 的构造函数是私有的
而 MonoState 的的构造函数是共有的

MonoState 和 Singleton 看起来很相似
但他们体现了不同的设计动机
MonoState 可以被大量实例化 (被实例化的对象 享有共同的 类状态),
而 Singleton 就 只有一个 (它体现的是 全局的应用状态 )
41 楼 Saito 2009-06-08  
这个东西涉及到 Singleton 跟 MonoState .

   前段时间我们也讨论过. 不过像Math这种工具类. 它实际没有存在对象的必要. 这时就没有必要单例.
   并且大量的static的方法. 实际上是一种面向对象的倒退.

   我们可以写一个Gui程序. 在菜单用Singleton . 能把它写成纯 static的嘛? 我觉得使他丧失了很多东西. 不值得...
40 楼 步行者 2009-06-08  
abc130314 写道
例如,现在引用一个新的库,而现在需要扩展,或者修改其中一个类的功能。
而如果这个类全是用静态方法写的。除了修改源代码。很难实现。
但是如果用的单例,直接继承就可以了。这样可以完全体现对象的特征。
这是相对于,为什么用单例,而不用全静态方法的好处。(一般工具类,没有这么复杂的要求。所以一般没必要用单例。)

使用单例,就是确定了系统只用一个对象。或者说是大多数的系统都只需要引用一个对象。然后,方便你不再需要把这个对象 new 出来,再用一个方法或一个字段去引用。

一般我的标准是,如果一个类里面有多个方法调用同一个属性。那我一定会用单例。
如果所有的方法都只需要调用一个属性,或者不需要。那我绝对写成工具类。


你讲的是类继承对对象来说产生的益处
而不是 类继承对 单例(一种特殊对象,全局唯一) 来说产生的益处

39 楼 night_stalker 2009-06-08  
现在手写单例往往等于反模式,不要再纠缠了……
38 楼 abc130314 2009-06-08  
例如,现在引用一个新的库,而现在需要扩展,或者修改其中一个类的功能。
而如果这个类全是用静态方法写的。除了修改源代码。很难实现。
但是如果用的单例,直接继承就可以了。这样可以完全体现对象的特征。
这是相对于,为什么用单例,而不用全静态方法的好处。(一般工具类,没有这么复杂的要求。所以一般没必要用单例。)

使用单例,就是确定了系统只用一个对象。或者说是大多数的系统都只需要引用一个对象。然后,方便你不再需要把这个对象 new 出来,再用一个方法或一个字段去引用。

一般我的标准是,如果一个类里面有多个方法调用同一个属性。那我一定会用单例。
如果所有的方法都只需要调用一个属性,或者不需要。那我绝对写成工具类。
37 楼 wendong007 2009-06-08  
你们都是神一样的人……

回去做C开发吧
36 楼 flhs 2009-06-08  
呵呵 这个问题我也曾经考虑过 最后得到到结论是:只有一个实例和没有实例其实没什么差别。
35 楼 yuzhitao 2009-06-08  
确实有时也应该质疑一下设计模式
34 楼 步行者 2009-06-08  
abc130314 写道
如果构造方法是 protected 的话。单例的最大意义应该就是继承了。JDK 里面很多单例都是子类保护的。
如果是 private 的话。意义不大。
而且,如果 用 private static Singleton instance = null; 这样的形似。还有一个意义就是延迟加载。
如果不用单例,那势必所以的初始化都必须写在 静态块 里面。
而如果用单例,在某些系统中,我不需要调用单例对象,只需要执行类的某些 静态方法。就不会执行初始化。


单例的继承请举例说明一下,以及它的优势

静态类的一些初始化工作 可以不在加载时进行
我也可以定义一个静态初始化方法 来做一些
初始化工作,不一定在加载时就把所有初始化工作
都做了。

33 楼 步行者 2009-06-08  
spider-dog 写道
如果我想保证一个类只有两个(或三个。。。)实例怎么办?比方说我想自己实现一个Bool类。

你可以用 java 的 枚举类型(enum) 来自己实现Bool类

32 楼 qqj_1979 2009-06-08  
通过单例模式和类的静态方法都可以达到目的。

个人觉得没有必要过于去深究这个东东。
31 楼 spider-dog 2009-06-08  
我感觉有三个理由:
1) 类可能需要实现接口。比如说,我有一个接口I,类C1和C2都需要实现接口I而且还只能有一个实例,这时候就不能用工具类来实现。
2) 如何测试,如何mock你的单例?这个可能仍然和接口有关。
3) 单例这个名字可能有一点误导。 如果我想保证一个类只有两个(或三个。。。)实例怎么办?比方说我想自己实现一个Bool类。

最后,没有实例的类应该确实也是单例模式的一种实现方式吧
30 楼 abc130314 2009-06-08  
如果构造方法是 protected 的话。单例的最大意义应该就是继承了。JDK 里面很多单例都是子类保护的。
如果是 private 的话。意义不大。
而且,如果 用 private static Singleton instance = null; 这样的形似。还有一个意义就是延迟加载。
如果不用单例,那势必所以的初始化都必须写在 静态块 里面。
而如果用单例,在某些系统中,我不需要调用单例对象,只需要执行类的某些 静态方法。就不会执行初始化。
29 楼 hsbljyy 2009-06-08  
我觉得单例的一个好处,应该是可以使用父类,也就是继承。它可以继承父类的protected以上级别的属性跟方法,如果使用静态类,你想用这些东西,你就把要用到的方法全部都扔到这个类里面来,我不知道我的理解是否正确,提个观点大家讨论一下!
28 楼 neptune 2009-06-08  
接口这个关,就过不了
27 楼 步行者 2009-06-08  
谢谢大家对这个帖子的关注

对于一个设计模式 我的理解它就像一个经典招式
那么我们是不是掌握了一些经典招式后就能独步武林了呢
我不知道 反正我还没有充分驾驭这些招式
但我想一个武林高手 要做到百战百胜 必定知己知彼

我们需要了解这些设计模式,但我们也要充分思考这些模式,
到底这些模式 背后 隐藏着什么样的动机,在什么情况下运用
才能发挥它的作用。

以前对模式的运用让我产生过一些困惑,模式带来的灵活度与
复杂度怎么来权衡,滥用模式只会增加系统的复杂性与维护成本,
那么权衡的标准又是什么, 我想是来源于经验和需求。

希望大家通过这个帖子也能得到小小启发。。



相关推荐

Global site tag (gtag.js) - Google Analytics