`
步行者
  • 浏览: 171384 次
  • 性别: 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
	}
}

 

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

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

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

但是不允许实例化,

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

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

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

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


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

而 类 不能。

 

 

 

分享到:
评论
26 楼 whaosoft 2009-06-07  
seraphim871211 写道
这帖子都有人投隐藏??

JE搞什么啊,投个良好冲下

其实我想给你良好 但我没那个能力
至于为什么都是单实例 我感觉不一定都是那样 你是不是看了 spring的配置的都是单实例呢
25 楼 seraphim871211 2009-06-07  
这帖子都有人投隐藏??

JE搞什么啊,投个良好冲下
24 楼 步行者 2009-06-07  
fjlyxx 写道
步行者 写道
fjlyxx 写道

将类定义为final吧

为什么要将类定义为 final 呢
即使被其他类继承 ,它的状态还是唯一的
它的子类可以使用父类的静态方法和静态属性
,却不会在内存中创造一份父类静态方法和静态
属性的的拷贝,
类的状态是唯一的,不能通过继承复制它,只能
通过特定接口访问它


呵呵,这是态度问题..其实没区别... 这个和写 class test和 class Test一样的道理. 规范.
一个是cannot subclass the final class
另一个是
Implicit super constructor   is not visible for default constructor. Must define an explicit constructor


呵呵 采纳意见。
不final 确实肯能会引起混淆,而且子类也可以实例化对象


23 楼 fjlyxx 2009-06-07  
步行者 写道
fjlyxx 写道

将类定义为final吧

为什么要将类定义为 final 呢
即使被其他类继承 ,它的状态还是唯一的
它的子类可以使用父类的静态方法和静态属性
,却不会在内存中创造一份父类静态方法和静态
属性的的拷贝,
类的状态是唯一的,不能通过继承复制它,只能
通过特定接口访问它


呵呵,这是态度问题..其实没区别... 这个和写 class test和 class Test一样的道理. 规范.
一个是cannot subclass the final class
另一个是
Implicit super constructor   is not visible for default constructor. Must define an explicit constructor
22 楼 步行者 2009-06-07  
dennis_zane 写道
楼主,你说的其实没问题,单例就是一个全局访问点,用全部是静态变量和静态方法的类来做同样可以。我看过这样的讨论,最后的结论是单例模式比之全静态类来说唯一的好处就是,你可以很容易将单例改成多实例,这个理由很薄弱。


支持这个观点,不过这个理由确实有点薄弱,呵呵
21 楼 步行者 2009-06-07  
qzzlw 写道
类的属性是全局的,系统一启动就已经在全局静态数据区分配好了资源,而单例是对象,只有在需要的时候才在堆内分配资源来放置实例属性。从封装的角度或者资源占用的角度来看 ,单例可能会更好一些。


类不是在系统一启动时就加载,而是在第一次引用,或实例化时进行加载
还有另一种方法加载类
Class.forName("XXX");
反而对象的初始化要先加载类,
再进行实例化。
所以我觉得从资源占用的角度来看 ,类反而要好一些。

至于封装,也可以通过私有静态属性来封装类状态,
我觉得这也不是问题



20 楼 qzzlw 2009-06-07  
类的属性是全局的,系统一启动就已经在全局静态数据区分配好了资源,而单例是对象,只有在需要的时候才在堆内分配资源来放置实例属性。从封装的角度或者资源占用的角度来看 ,单例可能会更好一些。
19 楼 dennis_zane 2009-06-07  
楼主,你说的其实没问题,单例就是一个全局访问点,用全部是静态变量和静态方法的类来做同样可以。我看过这样的讨论,最后的结论是单例模式比之全静态类来说唯一的好处就是,你可以很容易将单例改成多实例,这个理由很薄弱。

18 楼 步行者 2009-06-07  
flyspider 写道
楼主的做法是单了,可惜没有"例"
静态属性和静态方法的做法不是说不可以达到目标,只是这样做初始化工作就交给了JVM,这样的做法基本丧失了主控性,也不利于测试,那么既然单例的做法更好,何乐不为呢?


如果对象不是单例,这种说法我就接受了
因为对象是单例,它的初始化实际上分为两步的:
    1,加载单例对应的类
    2,创建一个单例
而类也只会被加载一次,而且不一定非要在加载时 把所有的初始化工作都做了。
我们也可以在使用前做初始化工作。
所以我不觉得这是单例的优势!
17 楼 步行者 2009-06-07  
treenode 写道
如果单例对象需要 a. 从反序列化得来, b. 用Spring这样的框架装配而成,c. 根据实际的运行环境,向单例的构造函数传递不同的参数,那么使用类的静态成员就是不合适的。如果没有这些要求,以类为单例是足够了。



你的这三种情况 是针对对象的,因为类不是对象,确实不能满足。
不过类可以通过其他途径满足 这三种情况所要达到的目的。
a , 对象序列化 确实不保存 静态属性,但类的内部状态不是不可以保存并恢复的。
b , Spring 容器是管理对象的,当然不能管理类,类也不需要管理,因为它只有一个
索引它只需要类名就可以了。
c , 对象才有构造函数 ,类当然没有。但类可以使用静态初始化方法初始化类的内部状态。
16 楼 flyspider 2009-06-07  
楼主的做法是单了,可惜没有"例"
静态属性和静态方法的做法不是说不可以达到目标,只是这样做初始化工作就交给了JVM,这样的做法基本丧失了主控性,也不利于测试,那么既然单例的做法更好,何乐不为呢?
15 楼 night_stalker 2009-06-07  
步行者 写道
frenchmay 写道
确保当前虚拟机中只存在一份类的实例,为了在不同对象中安全地共享对象。
另外你写的这个单例的方法并非线程安全


线程安全很重要,但这不是讨论的重点
问题是 单例能线程安全 ,类也能线程安全啊。
为什么用单例 而 不用用静态属性和静态方法构造的类
来表达这种唯一性呢?


感觉不到好处就别用。不要成为 Stinkleton。
另外用 DI 就已经很方便了,现在手写 singleton 已经成为反模式了……
14 楼 步行者 2009-06-07  
frenchmay 写道
确保当前虚拟机中只存在一份类的实例,为了在不同对象中安全地共享对象。
另外你写的这个单例的方法并非线程安全


线程安全很重要,但这不是讨论的重点
问题是 单例能线程安全 ,类也能线程安全啊。
为什么用单例 而 不用用静态属性和静态方法构造的类
来表达这种唯一性呢?
13 楼 night_stalker 2009-06-07  
把构造函数私有化的那步放到最终具体类中,依然能用多态啊。


原型的对象系统就没这个问题,既然没有 class,就没有特意弄 singleton 的必要了。
引用
In a prototype-based programming language, where objects but not classes are used, a "singleton" simply refers to an object without copies or that is not used as the prototype for any other object. Example in Io:

Foo := Object clone
Foo clone := Foo
12 楼 步行者 2009-06-07  
fjlyxx 写道

将类定义为final吧

为什么要将类定义为 final 呢
即使被其他类继承 ,它的状态还是唯一的
它的子类可以使用父类的静态方法和静态属性
,却不会在内存中创造一份父类静态方法和静态
属性的的拷贝,
类的状态是唯一的,不能通过继承复制它,只能
通过特定接口访问它
11 楼 frenchmay 2009-06-07  
确保当前虚拟机中只存在一份类的实例,为了在不同对象中安全地共享对象。
另外你写的这个单例的方法并非线程安全
10 楼 treenode 2009-06-07  
如果单例对象需要 a. 从反序列化得来, b. 用Spring这样的框架装配而成,c. 根据实际的运行环境,向单例的构造函数传递不同的参数,那么使用类的静态成员就是不合适的。如果没有这些要求,以类为单例是足够了。

9 楼 ravenex 2009-06-07  
楼主问得好,这问题困惑小的多时,期待有大大完整解答一个
kaka11 写道
至于静态方法的话,是会限制了多态,所以很多情况在oo编程中它是不被用的,除非你确定你的类完全不需要,不可能使用到多态,比如像工具类,或者像active record里面的那些find方法,很多时候技术并没有对错,只是适合不适合和你是否需要一些oo的灵活性了。

常见的单例模式实现方法由于把构造器设为private,一样限制了多态,而且它的方法一般以实例方法为主,比静态方法慢。据说单例模式比静态类容易测试,因为有办法mock
8 楼 night_stalker 2009-06-07  
我觉得单例的原因是类型不能当对象用。
譬如函数传参数时你得传个对象或值,不能传类型。
所以把 static 的东西都改成非 static 的,强制只能实例化一遍,传递唯一的实例,就能模拟“传递类型”的效果了。另外 static 成员在继承的时候一坨乱糟糟也是个原因。
7 楼 rgrg 2009-06-07  
这样会损失面向对象的特性

相关推荐

    Singleton

    只有在INSTANCE为null时,才进行同步,这样大多数情况下都不需要同步。 ```java public class Singleton { private volatile static Singleton INSTANCE; private Singleton() {} public static Singleton ...

    C++完美实现Singleton模式

    如果项目中有多个Singleton类需要实现,那么重复的代码将会增多。为了解决这个问题,可以通过模板化Singleton类来减少代码量: ```cpp #pragma once #include using namespace std; using namespace C2217::Win32;...

    Qt qml Singleton 单例模式

    - 如果Singleton需要在C++中初始化,可以使用`setObject`方法在C++侧设置Singleton的实例。 综上所述,Qt Qml的Singleton模式为全局共享对象提供了方便,使得在Qml环境中管理和访问同一对象变得简单。通过C++和Qml...

    C++ 实现的singleton 模式

    // 如果有需要初始化的数据,可以在这里声明 // ... }; ``` 在`Singleton.cpp`中,我们实现`getInstance()`方法: ```cpp #include "Singleton.h" // 单例的静态成员变量,存储唯一实例 Singleton* Singleton::...

    singleton设计模式java实现及对比

    缺点:如果Singleton需要持有外部引用,可能会导致内存泄漏。 综上所述,Singleton模式的实现方式各有优劣,选择哪种方式取决于具体的应用场景和性能需求。在实际开发中,应根据项目需求选择最适合的Singleton实现...

    Singleton Pattern 源码

    单例模式(Singleton Pattern)是软件设计模式中的一种,它保证一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下非常有用,比如控制资源的唯一性、全局配置对象或者缓存服务等。本篇文章将深入探讨...

    Singleton 单例模式

    这种模式常用于系统资源管理,比如数据库连接、线程池或者缓存服务等,因为这些资源往往需要全局共享且控制其生命周期。 单例模式的核心思想在于控制类的构造函数,防止外部直接实例化。通常,我们会将构造函数设为...

    SingleTon的模板(template)化应用

    首先,我们需要理解单例模式的基本思想。单例模式通常包含两个关键点:一是控制类的实例化过程,只允许创建一个实例;二是提供一个全局访问点,使得任何地方都可以获取到这个唯一的实例。传统的C++单例实现可能使用...

    Java常用设计模式(SingleTon、FactoryMethod、AbstractFactory)

    Java设计模式是面向对象编程中的重要概念,它们是解决常见问题的经验总结,为代码的可重用性、可维护性和可扩展性提供了指导。这里我们将深入探讨三种常见的Java设计模式:单例(Singleton)、工厂方法(Factory ...

    linux 下线程安全的singleton

    singleton是最常见的设计模式,但是要设计好却是不容易,尤其是多线程的时候,需要考虑线程安全的问题.

    Java 单例模式Singleton

    简单的单例模式举例Singleton 分为恶汉式 懒汉式

    单例模式Singleton

    单例模式(Singleton Pattern)是一种常用的软件设计模式,它的核心思想是确保一个类在整个应用程序中只有一个实例存在,并提供一个全局访问点来获取这个实例。这种模式在很多场景下非常有用,比如管理系统资源、...

    Singleton.rar

    总结来说,单例模式是一种限制类实例化的模式,适用于需要全局唯一对象的场景。在C++中,我们通常通过封锁构造函数、创建静态成员变量和提供公共的获取实例方法来实现。通过学习和实践这样的代码示例,开发者可以...

    SingletonTemplate

    在继承SingletonTemplate时,子类只需要关注自己的业务逻辑,无需关心单例的实现细节。这样的设计遵循了“开闭原则”,即对扩展开放,对修改关闭。 在实际编程中,需要注意单例模式的适用场景和潜在问题。虽然单例...

    (创建型模式)Singleton模式

    除了上述实现方式,还需要注意Singleton模式的一些扩展和讨论。例如,Singleton模式破坏了类的封装性,使得类的实例化过程不再由类自身控制,而是外部代码控制。这在某些情况下可能引发问题,比如测试和序列化。为了...

    Laravel开发-singleton-pattern

    Singleton确保一个类只有一个实例,并提供一个全局访问点,这样可以避免创建多个对象导致资源浪费,尤其适用于那些创建开销大或需要全局共享状态的类。 首先,我们要理解什么是单例模式。单例模式是一种创建型设计...

    单例极致 singleton C++

    1、没有构造函数(DEFINE_SINGLETON_DEFAULT); 2、有构造函数,构造函数没有参数(DEFINE_SINGLETON_CONSTRUCT_NO_PARAM); 3、有构造函数,构造函数有没有参数版本(DEFINE_SINGLETON_CONSTRUCT_WITH_DEFAULT)...

    Loki singleton

    然后,你可以为你的类定义一个Singleton模板实例,以确保该类在整个应用程序中只存在一个实例。以下是一个基本的示例: ```cpp #include <Loki/Singleton.h> class MyClass { public: // 确保你的构造函数是私有...

    单例模式Singleton(java源码)

    Singleton模式包含的角色只有一个,就是Singleton。Singleton拥有一个私有构造函数,确保用户无法通过new直接实例化它。除此之外,该模式中包含一个静态私有成员变量instance与静态公有方法Instance()。Instance()...

Global site tag (gtag.js) - Google Analytics