深入浅出设计模式——单例模式(Singleton Pattern)
模式动机
对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。
如何保证一个类只有一个实例并且这个实例易于被访问呢?定义一个全局变量可以确保对象随时都可以被访问,但不能防止我们实例化多个对象。
一个更好的解决办法是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。这就是单例模式的模式动机。
模式定义
单例模式(Singleton Pattern):单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。
单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。单例模式是一种对象创建型模式。单例模式又名单件模式或单态模式。
Singleton Pattern: Ensure a class has only one instance and provide a global point of access to it.
Frequency of use: medium high
UML图
模式结构
单例模式包含如下角色:
Singleton:单例
模式分析
单例模式的目的是保证一个类仅有一个实例,并提供一个访问它的全局访问点。单例模式包含的角色只有一个,就是单例类——Singleton。单例类拥有一个私有构造函数,确保用户无法通过new关键字直接实例化它。除此之外,该模式中包含一个静态私有成员变量与静态公有的工厂方法,该工厂方法负责检验实例的存在性并实例化自己,然后存储在静态成员变量中,以确保只有一个实例被创建。
在单例模式的实现过程中,需要注意如下三点:
单例类的构造函数为私有;
提供一个自身的静态私有成员变量;
提供一个公有的静态工厂方法。
实例:身份证号码
在现实生活中,居民身份证号码具有唯一性,同一个人不允许有多个身份证号码,第一次申请身份证时将给居民分配一个身份证号码,如果之后因为遗失等原因补办时,还是使用原来的身份证号码,不会产生新的号码。
Singleton.cs
namespace SingletonPattern
{
class Singleton
{
private static Singleton instance;
//构造方法让其private,这就堵死了外界利用new创建此类实例的可能
private Singleton()
{
}
//此方法是获得本类实例的唯一全局访问点
public static Singleton GetInstance()
{
//若实例不存在,则new一个新实例,否则返回已有的实例
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
客户端代码
using System; namespace SingletonPattern
{
class Program
{
static void Main(string[] args)
{
Singleton s1 = Singleton.GetInstance();
Singleton s2 = Singleton.GetInstance();
if (s1 == s2)
{
Console.WriteLine("两个对象是相同的实例");
} Console.Read();
}
}
}
单例模式的优点
提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它,并为设计及开发团队提供了共享的概念。
由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统的性能。
允许可变数目的实例。我们可以基于单例模式进行扩展,使用与单例控制相似的方法来获得指定个数的对象实例。
单例模式的缺点
由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
单例类的职责过重,在一定程度上违背了“单一职责原则”。因为单例类既充当了工厂角色,提供了工厂方法,同时又充当了产品角色,包含一些业务方法,将产品的创建和产品的本身的功能融合到一起。
滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;现在很多面向对象语言(如Java、C#)的运行环境都提供了自动垃圾回收的技术,因此,如果实例化的对象长时间不被利用,系统会认为它是垃圾,会自动销毁并回收资源,下次利用时又将重新实例化,这将导致对象状态的丢失。
模式适用环境
在以下情况下可以使用单例模式:
系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器,或者需要考虑资源消耗太大而只允许创建一个对象。
客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。
在一个系统中要求一个类只有一个实例时才应当使用单例模式。反过来,如果一个类可以有几个实例共存,就需要对单例模式进行改进,使之成为多例模式。
深入浅出设计模式——单例模式(Singleton Pattern)的更多相关文章
- 浅谈设计模式--单例模式(Singleton Pattern)
题外话:好久没写blog,做知识归纳整理了.本来设计模式就是个坑,各种文章也写烂了.不过,不是自己写的东西,缺少点知识的存在感.目前还没做到光看即能记住,得写.所以准备跳入设计模式这个大坑. 开篇先贡 ...
- 设计模式之单例模式(Singleton Pattern)
单例模式 单例模式(Singleton Pattern)在java中算是最常用的设计模式之一,主要用于控制控制类实例的数量,防止外部实例化或者修改.单例模式在某些场景下可以提高系统运行效率.实现中的主 ...
- 乐在其中设计模式(C#) - 单例模式(Singleton Pattern)
原文:乐在其中设计模式(C#) - 单例模式(Singleton Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 单例模式(Singleton Pattern) 作者:weba ...
- 设计模式系列之单例模式(Singleton Pattern)——确保对象的唯一性
模式概述 模式定义 模式结构图 饿汉式单例与懒汉式单例 饿汉式单例 懒汉式单例 模式应用 模式在JDK中的应用 模式在开源项目中的应用 模式总结 主要优点 适用场景 说明:设计模式系列文章是读刘伟所著 ...
- 【设计模式】单例模式 Singleton Pattern
通常我们在写程序的时候会碰到一个类只允许在整个系统中只存在一个实例(Instance) 的情况, 比如说我们想做一计数器,统计某些接口调用的次数,通常我们的数据库连接也是只期望有一个实例.Windo ...
- 二十四种设计模式:单例模式(Singleton Pattern)
单例模式(Singleton Pattern) 介绍保证一个类仅有一个实例,并提供一个访问它的全局访问点. 示例保证一个类仅有一个实例. Singleton using System; using S ...
- 抽象工厂(Abstract Factory),工厂方法(Factory Method),单例模式(Singleton Pattern)
在谈工厂之前,先阐述一个观点:那就是在实际程序设计中,为了设计灵活的多态代码,代码中尽量不使用new去实例化一个对象,那么不使用new去实例化对象,剩下可用的方法就可以选择使用工厂方法,原型复制等去实 ...
- 十次艳遇单例设计模式(Singleton Pattern)
1.引言 单例设计模式(Singleton Pattern)是最简单且常见的设计模式之一,在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访 ...
- 设计模式 单例模式(Singleton) [ 转载2 ]
设计模式 单例模式(Singleton) [ 转载2 ] @author java_my_life 单例模式的结构 单例模式的特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一实例. 单例类 ...
随机推荐
- mysql集群 MySQL Cluster
<?php /* 郑重说明2015年6月11日16:28:14,目前为止MySQL Cluster 社区版不支持INNODB,商业版支持,但是授权价格20W左右,so看此文档之前,考虑下钱 My ...
- maven使用本地jar包
引入本地jar包 方式一:将本地Jar包安装到本地仓库,再按常规方式引用 mvn install:install-file -Dfile=libs\tools.jar -DgroupId=com.su ...
- log4j.properties 配置的学习整理
参考资料: log4j.properties:用来做什么的(日志) Log4j:由2部分组成 :loggers(记录器) ----日志的类别 appender(输出源) ...
- php://input,php://filter,data URI schema的那些事
一.php://input一句话木马 在调研dedecms的历史漏洞时,发现了dedecms安装文件曾经出过被植入后门的漏洞(SSV-ID站点include目录下shopcar.class.php文件 ...
- 为什么微信android图片质量会比iphone的差?
为什么微信android图片质量会比iphone的差? 我们团队最初也纠结过这个问题,费了半天劲.绕了好大圈,直到最后才发现,原来这是谷歌犯得一个“小”错误,而且一直错到了今天. 谷歌的错就在于:li ...
- Python开发程序:选课系统
本节作业: 选课系统 角色:学校.学员.课程.讲师要求:1. 创建北京.上海 2 所学校2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开3. ...
- Win10如何设置防火墙开放特定端口 windows10防火墙设置对特定端口开放的方法
Win10防火墙虽然能够很好地保护我们的系统,但同时也会因限制了某些端口,而给我们的操作带了一些不便.对于既想使用某些端口,又不愿关闭防火墙的用户而言,在Win10系统中设置防火墙开放特定端口就非常必 ...
- Python基础、collections补充
collections collections是Python数据类型的补充,可以实现Counter计数.可命名元组(namedtuple).默认字典.有序字典.双向队列等功能 参考:http://py ...
- 个人对AutoResetEvent和ManualResetEvent的理解(转载)
仅个人见解,不对之处请指正,谢谢. 一.作用 AutoResetEvent和ManualResetEvent可用于控制线程暂停或继续,拥有重要的三个方法:WaitOne.Set和Reset. 这三个方 ...
- 20145320 《Java程序设计》第10周学习总结
20145320 <Java程序设计>第10周学习总结 教材学习内容总结 网络编程 计算机网络概述 网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输. 按照计算机网络的定义 ...