`

【编程思想】面向对象中的getInstance()与单例模式

阅读更多


今天看到这样的一段代码,觉得有必要说一下。




private PackageManager() {		
	}
	
	private static  PackageManager instance = new  PackageManager ();
	
	public static  PackageManager getInstance() {
		return instance;
	}


可以看到,构造函数是私有的,而唯一公开的供我们调用一个对象的接口不是构造函数,而是一个getInstance()函数,为什么不将构造函数设置为公有,直接new 一个对象呢,这样做有什么好处呢


这种构造对象的方式,我们一般称之为单例模式,单例模式,顾名思义,只允许一个对象存在,无论是什么时候,你构造和调用的对象都永远是那个实例。


单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。


很明显,单例模式阻止了大量对象的生成,节省了内存,最重要的一点还是,它适用于很多需要处理资源冲突的地方,比如,每台计算机可以有若干个打印机,但只能有一个Printer Spooler,避免两个打印作业同时输出到打印机。


单例模式的要点

      显然单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。所有的客户对象共享一个单例对象。单例对象持有对自己的引用。  

      一些资源管理器常常设计成单例模式。  

      在计算机系统中,需要管理的资源包括软件外部资源,每台计算机可以有若干传真卡,但是只应该有一个软件负责管理传真卡,以避免出现两份传真作业同时传到传真卡中的情况。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。  

     需要管理的资源包括软件内部资源,譬如,大多数的软件都有一个(甚至多个)属性(properties)文件存放系统配置。这样的系统应当由一个对象来管理一个属性文件。        需要管理的软件内部资源也包括譬如负责记录网站来访人数的部件,记录软件系统内部事件、出错信息的部件,或是对系统的表现进行检查的部件等。这些部件都必须集中管理,不可政出多头。

  这些资源管理器构件必须只有一个实例,这是其一;它们必须自行初始化,这是其二;允许整个系统访问自己这是其三。因此,它们都满足单例模式的条件,是单例模式的应用。


当一个类的实例可以有且只可以一个的时候就需要用到了。为什么只需要有一个呢?有人说是为了节约内存。本人对这个说法持保留态度。只有一个实例确实减少内存占用,可是我认为这不是使用单例模式的理由。我认为使用单例模式的时机是当实例存在多个会引起程序逻辑错误的时候。比如类似有序的号码生成器这样的东西,怎么可以允许一个应用上存在多个呢?


C#中的单例模式

  用法说明:保证一个类仅有一个实例,并提供一个访问它的全局访问点

  实现要点Singleton模式是限制而不是改进类的创建;Singleton类中的实例构造器可以设置为Protected以允许子类派生;Singleton模式一般不要支持Icloneable接口,因为这可能导致多个对象实例,与Singleton模式的初衷违背;Singleton模式一般不要支持序列化,这也有可能导致多个对象实例,这也与Singleton模式的初衷违背;Singleton只考虑了对象创建的管理,没有考虑到销毁的管理,就支持垃圾回收的平台和对象的开销来讲,我们一般没必要对其销毁进行特殊的管理;理解和扩展Singleton模式的核心是“如何控制用户使用new对一个类的构造器的任意调用”;可以很简单的修改一个Singleton,使它有少数几个实例,这样做是允许的而且是有意义的。  

     优点

          实例控制:Singleton 会阻止其他对象实例化其自己的 Singleton 对象的副本,从      而确保所有对象都访问唯一实例

          灵活性:因为类控制了实例化过程,所以类可以更加灵活修改实例化过程

     缺点

           开销:虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将      仍然需要一些开销。可以通过使用静态初始化解决此问题,上面的五种实现方式中已经        说过了。  

           可能的开发混淆:使用 singleton 对象(尤其在类库中定义的对象)时,开发人员      必须记住自己不能使用 new 关键字实例化对象。因为可能无法访问库源代码,因此应        用程序开发人员可能会意外发现自己无法直接实例化此类。


     对象的生存期:Singleton 不能解决删除单个对象的问题。在提供内存管理的语言中        (例如基于 .NET Framework 的语言),只有 Singleton 类能够导致实例被取消分        配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除对        象实例,但这样会导致 Singleton 类中出现悬浮引用。  


     适用性当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时;当这个      唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的        实例时。  

     

      应用场景:

       PC机中可能有几个串口,但只能有一个COM1口的实例;

          系统中只能有一个窗口管理器。


  实现要素:

  至少在目前所有了解的语言中,静态变量(这是c/c++的叫法,其他语言或有不同)是实现单例模式的要素。



    不过,对于这种单例模式,还是要注意适用范围,用的恰当,方能大有裨益,不恰当的话,反而会弄巧成拙。


分享到:
评论

相关推荐

    单例模式java代码

    getInstance()方法判断是否存在空闲的对象,存在将该空闲对象的isBusy置为true,并返回该对象;如果不存在空闲对象则返回null。LimitInstanceClass有一个release()方法,该方法将对象的isBusy置为false。...

    单例模式的扩展及其应用

    getInstance()方法判断是否存在空闲的对象,存在将该空闲对象的isBusy置为true,并返回该对象;如果不存在空闲对象则返回null。LimitInstanceClass有一个release()方法,该方法将对象的isBusy置为false。...

    android SQLite DBHelper 单例模式 实现

    android SQLite DBHelper 单例模式 实现 dbhelper=DBHelper.getInstance(this);

    单例模式PHP实现代码类.zip

    介绍一个单例模式PHP实现代码类,getInstance()方法必须设置为公有的,必须调用此方法,对象方法不能访问普通的对象属性,所以$_instance需要设为静态的

    php面向对象值单例模式

    简单的说,一个对象(在学习设计模式之前,需要比较了解面向对象思想)只负责一个特定的任务; 单例类: 1、构造函数需要标记为private(访问控制:防止外部代码使用new操作符创建对象),单例类不能在其他类中实例...

    java 设计模式 单例模式

    //单例模式,始终只产生一个对象 /*public class SingleTest { public static void main(String[] args) { SingleTon singleTon1=SingleTon.getInstance(); SingleTon singleTon2=SingleTon.getInstance(); ...

    项目中用到的jdbc连接 单例模式

    * 这时候线程2会在判断instance==null的时候失败,返回一个不完整的intance对象。 * * 尝试最佳实现方法。在该方法中,Singleton有一个private类型静态内部类, * 内部类在外部类加载的时候并不会加载,只有在...

    设计模式之单例模式程序

    设计模式里面的单例模式程序 package com.rrppff; public class Singleton { private static String name; public static String getName() { return name; } public static void setName(String name) { ...

    php设计模式之单例模式实例分析

    简单的说,一个对象(在学习设计模式之前,需要比较了解面向对象思想)只负责一个特定的任务; 单例类: 1、构造函数需要标记为private(访问控制:防止外部代码使用new操作符创建对象),单例类不能在其他类中实例...

    PHP单例模式详解及实例代码

    单例模式是指整个应用中某个类只有一个对象实例的设计模式。具体来说,作为对象的创建方式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局的提供这个实例。它不会创建实例副本,而是会向单例类...

    使用Java单例模式实现一个简单的日志记录器.txt

    这段代码实现了一个简单的日志记录器Logger,其中使用了Java的单例模式。在类的构造方法中,首先定义了一个静态变量instance,用于保存Logger的唯一实例。然后定义了一个静态锁对象lock,用于保证线程安全。接着定义...

    PHP 面向对象程序设计(oop)学习笔记(三) – 单例模式和工厂模式

    当需要保证某个对象只能有一个实例的时候,单例模式非常有用。它把创建对象的控制权委托到一个单一的点上,任何时候应用程序都只会仅有一个实例存在。单例类不应该可以在类的外部进行实例化一个单例类应该具备以下几...

    Javascript实现单例模式

    比如在整个系统的配置文件中,配置数据有一个单例对象进行统一读取和修改,其他对象需要配置数据的时候也统一通过该单例对象来获取配置数据,这样就可以简化复杂环境下的配置管理。  单例模式的思路是:一个类能...

    php设计模式 Singleton(单例模式)

    php /** * 单例模式 * * 保证一个类仅有一个实例,并提供一个访问它的全局访问点 * */ class Singleton { static private $_instance = null; private function __construct() { } static public function ...

    PHP单例模式详细介绍

    单例模式是指整个应用中某个类只有一个对象实例的设计模式。具体来说,作为对象的创建方式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局的提供这个实例。它不会创建实例副本,而是会向单例类...

    多线程下的单例模式优化

    这是一个关于多线程下的单例模式优化代码。public class Singleton { private static Singleton instance; private Singleton (){ } public static Singleton getInstance(){ //对获取实例的方法进行同步 if...

    C++单例模式应用实例

    本文实例讲述了C++单例模式及其相关应用方法,分享给大家供大家参考。具体方法分析如下: 定义: 一个类有且仅有一个实例,并且提供一个访问它的全局访问点。 要点: 1、类只能有一个实例; 2、必须自行创建此实例;...

    php单例模式的简单实现方法

    php单例模式的简单实现方法 <?.../** * 设计模式之单例模式 ...* 使用单例模式生成一个对象后, * 该对象可以被其它众多对象所使用。 */ class Example { //保存例实例在此属性中 private static $_inst

    JAVA单例模式的几种实现方法

    1 饿汉式单例类.在类初始化时,已经自行实例化 class EagerSingleton { private static final EagerSingleton m_instance = new EagerSingleton(); /** * 私有的默认构造子 */ private EagerSingleton() ...

    多例模式java实现

    单例模式的扩展及应用。 编写一个类LimitInstanceClass,该类最多可以实例化指定个数实例。实例的个数用配置文件InstanceLimit.cfg指定。例如,如果InstanceLimit.cfg的内容为2,则LimitInstanceClass最多可以同时...

Global site tag (gtag.js) - Google Analytics