Singleton模式与全局变量

最近开始学习设计模式了,我从最简单的singleton模式开始学起,大概理解了该模式,就将各各书本上对该模式的理论部分摘录了下来。
1、Singleton模式可以解决什么问题或者说我们使用它的动机是什么?:几乎在每个应用程序中,都需要有一个从中进行全局访问和维护  某种类型数据的区域。在面向对象系统中也有这种情况,在此类系统中,在任何给定时间只应运行一个类或某个类的一组预定义数量  的实例。例如,当使用某个类来维护增量计数器时,此简单的计数器类需要跟踪在多个应用程序领域中使用的整数值。此类需要能够  增加该计数器并返回当前的值。对于这种情况,所需的类行为应该仅使用一个类实例来维护该整数,而不是使用其它类实例来维护该  整数。
   最初,人们可能会试图将计数器类实例只作为静态全局变量来创建。这是一个通用的方法,但实际上只解决一部分问题;他解决  了全局可访问性问题,但没有采取任何措施来确保在任何给定的时间只运行一个类实例。应该由类本身来负责只使用一个类实例,而  不是由类用户来负责。应该始终不要让类用户来监视和控制运行的类实例的数量。
   所需要的是使用某种方法来控制如何创建类实例,然后确保在任何给定的时间只创建一个类实例。这会确切地给我们提供所需的  行为,并使客户端不必了解任何类细节。
 2、Sigleton模式的设计意图是:保证一个类只有一个对象实例,并提供一个访问对象实例的全局
  访问点。
  如果我们想实现一个全局范围可见的对象以替代麻烦缠身的全局变量,那么,最好的做法是将
  数据封装在一个特殊的类中,这个类严格管理数据的创建过程以保证数据的唯一性,同时不允
  许程序员随意创建该类的对象实例(这可以通过将类的构造函数声明为priate 或protected 类
  型来实现)。虽然不能通过类的构造函数获得对象实例,但可以从该类提供的静态成员函数得
  到该类唯一的对象实例的指针或引用。
 3、Singleton模式和全局变量有什么本质的区别?
 全局变量的问题:
  (1)变量名冲突:必须小心维护变量名规则,所有工程师在开发代码时,每遇到一个全局变量,
  都必须仔细分辨该变量究竟属于哪个模块、哪个程序。
  (2)偶合度难题:全局变量实际上增加了函数与模块之间的耦合度。用通俗的话说,需要访问
  某个特定全局变量的多个函数被该变量牢牢地“粘结”在一起,成为拆不散的一团乱麻。
  (3)单个实体问题:全局变量不能阻止程序员定义一个类的多个对象实例。如果没有其它技术
  手段帮助,保证一个类只有单个实例就全靠程序员的自觉。
  (4)初始化顺序:全局变量不能保证相互之间遵循特定的初始化顺序,这完全由编译器决定。
  对于类的对象实例,构造函数被调用的顺序有时就显得非常重要。
  (5)多线程访问:当多个并发的线程都需要访问某些全局变量时,我们必须使用各种同步机制,
  小心地保护这些全局变量,以免陷入并发冲突的泥潭。
 4、单件类的来源
  使用单件类最容易犯的一个错误就是按照原来结构化程序设计的思路考虑问题,把全局变量作为模块之间共享数据的的一个桥梁,即
 把多个局部变量收集起来,放进一个单件类中,这样是换汤不换药、新瓶装旧酒的做法,它虽然可以减少一些全局变量,部分地解决命名冲突问题,但是对系统的框架却没有任何好处,全局变量本身的风险依然存在。
  面向对象设计和开发技术的主旨是对数据和相关操作的封装。在面向对象理论开来,向全局变量这样可能无限制地增加模块间偶合关
 系的语言要素实在是过时的、危险的和应该抛弃的。在更加纯粹的面向对象语言,如Java 和C#中,我们实际上已经找不到了全局变量的  踪影,甚至连main函数也躲进了类结构内部。在Java和C#语言中,我们可以使用public类型的字段、方法或者属性来实现我们在C语言中  经常要用全局变量实现的功能。
  在系统中提炼单件类的根本方法应当是,在面向对象分析与面向对象设计的基础上,寻找哪些具有单件类的特性、生命周期较长的类 ,把它们改写成单件类的形式。在这样的分析和设计过程中,根本就没有全局变量存活的空间。
 5、  singleton模式的好处:
    跨平台:使用合适的中间件,可以把singleton模式扩展为跨多个JVM和多个计算机工作。
    适用于任何类:只需把一个类的构造函数变成私有额,并且在其中增加相应的静态函数和变量,就可以把这个类变成singleton。
  可以透过派生创建:给定一个类,可以创建它的一个singleton之类。
  延迟求值:如果singleton从未使用过,那么就决不会创建它。
 6、singleton模式的代价 :
  摧毁方法未定义:没有好的方法去摧厚一个singleton,或者解除其职责。即使添加一个decommission方法把theInstance置为null,系统中的其他模块仍然持有对该singleton实例的应用。这样,随后对Instance方法的调用会创建另外一个实例,致使同时存在两个实例。这个问题在C++中尤为严重,应为实例可以被摧毁,可能会导致去提领一个已被摧毁的对象。
  不能继承:从singleton类派生出来的类并不是singleton。如果要使其成为singleton,必须要增加所需的静态函数和变量。
  效率问题:每次调用Instance方法都会执行if语句。就大多数调用而言,if语句是多余的。
  不透明性:singleton的使用者知道它们正在使用一个singleton,因为它们必须要调用Instance方法。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值