锁定老帖子 主题:为什么需要Singleton
该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2009-06-08
Singleton如果序列化的话,还要注意序列化问题:
/** * @author kakachen */ public class SingletonSer implements Serializable { /** * */ private static final long serialVersionUID = -892694328982110567L; public static final SingletonSer INSTANCE = new SingletonSer(); private SingletonSer() { } private Object readResolve() throws ObjectStreamException { return INSTANCE; } } 这在<<effective java>>中都有讲到,不过该书的第2版中还讲了如果依赖于这种方法遇到了一些带有引用类型的实例变量必须把它置成transient,不然就有可能被攻击,具体的可以看该书第77条.所以如果是jdk1.5以上优先使用enum来作为序列化的Singleton. |
|
返回顶楼 | |
发表时间:2009-06-08
步行者 写道
因为我想不出来在什么情况下 单例可以满足需求 而 类 不能。 你的追求仅仅只满足于实现需求吗? 如果静态方法在多处被调用,将来某个时候,你希望它不是单例了,那么修改的代码量就非常大了。 如果把单例模式和工厂模式结合起来用,这个时候,需要修改的只是工厂内部的实现,调用单例的地方都不用修改。 更进一步,使用spring来注入,那么连工厂方法也不用写,只需要改一下配置,就可以灵活的在单例和实例之间切换了。
|
|
返回顶楼 | |
发表时间:2009-06-08
scvptz 写道
步行者 写道
因为我想不出来在什么情况下 单例可以满足需求 而 类 不能。 你的追求仅仅只满足于实现需求吗? 如果静态方法在多处被调用,将来某个时候,你希望它不是单例了,那么修改的代码量就非常大了。 如果把单例模式和工厂模式结合起来用,这个时候,需要修改的只是工厂内部的实现,调用单例的地方都不用修改。 更进一步,使用spring来注入,那么连工厂方法也不用写,只需要改一下配置,就可以灵活的在单例和实例之间切换了。
你说的都是针对对象得特性,类当然不能满足
至于跟工厂模式得结合 ,我觉得不会出现问题,你只需要把工厂类构造成Singleton就行了
|
|
返回顶楼 | |
发表时间:2009-06-08
Testability...
|
|
返回顶楼 | |
发表时间:2009-06-08
你这个只是一个简单的例子而已,如果在复杂的配置中,调用了N多的api,有的api不是static式的,不能写在static的方法中,这样,为了保证内存中的类只有一份,就需要singleton了!
|
|
返回顶楼 | |
发表时间:2009-06-08
moonranger 写道 Testability...
why not。。 |
|
返回顶楼 | |
发表时间:2009-06-08
hoorace 写道 你这个只是一个简单的例子而已,如果在复杂的配置中,调用了N多的api,有的api不是static式的,不能写在static的方法中,这样,为了保证内存中的类只有一份,就需要singleton了!
api不是static的 ,就不能static方法里调用这个api吗? 不是吧。。 |
|
返回顶楼 | |
发表时间:2009-06-09
可能在帖子里写的 AnotherSingleton 过于简单 下面是一个更加全面的 AnotherSingleton
public final class AnotherSingleton{ static{ //initialize AnotherSingleton ... } private static State innerState; public static synchronized void changeState(){ //change innerState ... } private AnotherSingleton(){} }
|
|
返回顶楼 | |
发表时间:2009-06-09
1,AnotherSingleton 为什么要被定义为 final ,
为了避免不必要的混淆,因为即使AnotherSingleton 被继承,运行中AnotherSingleton的子类在内存中并没有 创建所有静态方法和静态属性的副本,它只是一引用AnotherSingleton 类的静态属性和静态方法。即应用的状态还是保存在 AnotherSingleton类中。就像一个Singlton有两个名字, 我们通过这两个名字都可以引用这个Singlton,没必要, 这会引起不必要的混淆。 2,AnotherSingleton 的初始化放在 static{ //initialize AnotherSingleton ... } 中,类加载时一并初始化 AnotherSingleton 内部状态 但这会不会增加 JVM 启动时的负载呢, 不会,因为类在第一次被引用的时候才会被加载, 不是在 JVM 启动时就加载所有类。 |
|
返回顶楼 | |
发表时间:2009-06-09
不错 楼主 解释的越来越全面了
但我看了前面的回帖 如果 单例需要继承 其他类怎么办呢 AnotherSingleton 好像就不能满足这方面的要求了 |
|
返回顶楼 | |