锁定老帖子 主题:为什么需要Singleton
该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2009-07-30
步行者 写道
为什么需要 单例设计模式(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 } }
把类的所有方法都改为静态方法, 所有属性都改为静态属性(我们可以把 静态属性看成类的内部状态), 但是不允许实例化, 对类的操作相当于对单例的操作 而且类也可以维护内部状态(通过静态私有属性) 这完全满足了单例的要求。 不知道为什么需要单例模式。。。 因为我想不出来在什么情况下 单例可以满足需求 而 类 不能。
面向对象原则,违背封装跟多态,静态本来就违背面向对象原则,即为面向过程,正如楼上说的不如写C PS:楼主这代码也不算是一个绝对的单例,1.采用反射机制可以创建多个实例 2.未重写readReslove方法,反序列化产生2个实例 3.建议用枚举来做单例以上两种问题均已解决 4.同步方法改为Volatile跟块双重锁更佳
|
|
返回顶楼 | |
发表时间:2009-07-31
ninini 写道
wy19280469 写道
对象创建也需要加载类啊 --> 不是同一个内存空间 而static 只创建一个内存空间 对象创建是new 的过程 static 不用吧。 static 也支持并发啊 --> 如果定义static 属性的话 怎样保证并发的安全性? 同一个地址 你调用时一个值 如果你改变了这个值的时候 ,那下一个人调用的时候 还以为是原来的值怎么办?
??? 创建一了类的对象首先要加载相应类,当然只需要加载一次 static 可以保持线程同步,跟非static是一个道理啊
现在不是多核处理器了么,Static应该不像提倡Moore的单核时代了,Singleton,Static不向以前那么安全了,单核时候可以是同步,毕竟CPU只能在同一时间处理同一任务,多核的话就能同时处理CPU数量的任务,.NET里面都有控制各处理器处理指定线程的基础库,JAVA里面应该也有吧(暂时没找到) |
|
返回顶楼 | |
发表时间:2009-07-31
谨慎发表一下我的观点:
使用对象的情况: 如果不用单例,那么他就是一个普通对象,不排除有人获取另一个对象,那么如果这个单例是有状态的,并且需要保持这个状态的唯一性,那么多个对象就会出现问题 使用静态类情况: 类中静态变量是以开始就加载的,而单例是需要时分配堆。如果系统中有很多地方可能需要单例,那么应用一启动就加载这些类,会不会影响性能哪? |
|
返回顶楼 | |
发表时间:2009-08-17
我认为要不要单例有以下几个因素决定的
1: 这个类的实例是不是要频繁的被使用,并且里面成员变量是不会改变,或者很少改变的 如果要遇到以上情况,使用单例是个不错的选择 2: 第二 ,这个类,是不是会参与到多态中来, 如果要参与多态,那么就要放弃单例的写法 |
|
返回顶楼 | |
发表时间:2009-08-19
静态类的方法只能调用静态的。而非静态的方法都可以调用的。
|
|
返回顶楼 | |
发表时间:2009-09-02
Singleton 模式随着容器的出现,也渐渐走出历史舞台了
|
|
返回顶楼 | |
发表时间:2009-09-03
以前喜欢用静态类,不过现在较多用单例了。
首先从定义上说,静态类是违反面向对象原则的(书上看的,至于有什么问题暂时还没想清楚 ^_^),面向对象的原则是任何事物皆属于对象,静态类属于哪一个对象? 单例操作起来是很方便, 像接口,比如A、B 两个单例,同实现一个接口I,我可以在参数类型I中任选一个传递,这是静态类无法实现的。 还有代理,如果我要给一个单例的所有方法加一个缓存代理(实际应用中一种很常见的优化技术,缓存代理肯定是公共方法)。静态类就无法实现。 当然上面这些你可以用其他方法实现,但毕竟很麻烦,设计不就是为了简单易读吗。 如果你暂时不需要这些功能,也不能保证以后不会扩展到这个功能,所以…… 用单例吧。 哦,只私有化构造函数是无法保证单例的,因为有反射,要在构造方法里面加上throw才行。 |
|
返回顶楼 | |