一、单例模式(Singleton Pattern)

  单例模式要求一个类只能有一个实例,并且提供了一个全局的访问点。

比如说,中国主席的职位是Singleton,法律规定主席选举,任何时间只能有一个主席。

1、逻辑模型图:

2、物理模型图:

3、具体实现:

3.1、懒汉式单例:

//懒汉式单例
public sealed class Singleton//类设置属性为密封,不能被继承。
{
static Singleton instance=null;
Singleton()
{} public static Singleton Instance
{
get
{
if(instance==null)
{
instance=new Singleton();
}
return instance;
}
}
}
//这种实现方式,不是线程安全的,因为多线程的时候,可能会得到Singleton类的多个实例。
//假如有两个线程都去判断if(instance==null)并且得到结果为true,这时两个线程
//都会创建类Singleton的实例,违背了单例模式只能有一个类对象的实例的原则。

3.2、线程安全的单例

public sealed class Singleton
{
static Singleton instance=null;
static readonly object padlock=new object();//进程辅助对象 Singleton()
{ } public static Singleton Instance
{
get
{
lock(padlock)
{
if(instance==null)
{
instance=new Singleton();
}
return instance;
}
}
}
}
//对于线程来说是安全的,首先创建了一个进程的辅助对象,线程进入时先对padlock加锁
//然后在检测对象是否被创建,这样可以确保只有一个实例被创建,而且加入了锁,导致程序只有
//一个线程可以进去,对象实例有最先进入的那个线程创建,后面进来的线程进入时if(instance==null)为false
//不会再去创建对象实例,这种方式增加了额外的开销,损失了性能。

3.3、双重锁定

public sealed class Singleton
{
static Singleton instance=null;
static readonly object padlock=new object(); Singleton()
{ } public static Singleton Instance
{
get
{
if(instance==null)
{
lock(padlock)
{
if(instance==null)
{
instance=new Singleton();
}
}
}
return instance;
}
}
}
//对于多线程是安全的,而且并不是线程每次都加锁,只有判断对象实例没有被创建的时候才会加锁
//加锁还再进行对象是否被创建的判断。解决了线程并发的问题,但是实际上需要这样实现,大多数我们会
//使用静态初始化,但是静态初始化有自己的缺点,无法实现延迟初始化

3.4、静态初始化

public sealed class Singleton
{
static readonly Singleton instance=new Singleton();
//静态初始化的无参构造方法
static Singleton()
{ } Singleton()
{ } public static Singleton Instance
{
get
{
return instance;
}
}
}
//类标记为sealed不能继承,因为继承可能会增加实例。
//变量标记为readonly,表示只能在静态初始化时候或者在构造方法中分配变量。

3.5、延迟初始化

//如果类,结构,代理,枚举是外置,那么修饰符只有public和internal,默认是internal
//如果是内置的,修饰符默认是private
//举例: class A{}//类A是internal,internal表示同一个程序集中所有代码都可以访问类型或者成员
//其他程序集不可以访问。
//举例:class A
// {
// class B{}//类B是private
// }
public sealed class Singleton
{
Singleton()//类的构造函数默认为private
{ } public static Singleton Instance
{
get
{
return Lazy.instance;
}
} class Lazy//lazy默认是internal
{
static Lazy()
{ }
internal static readonly Singleton instance=new Singleton();
} }
//初始化的时候有一个Lazy类的一个静态成员来完成,这样实现了延迟初始化。

4、实现总结:

Singleton单例模式构造方法可以设置为protected,允许子类继承。

单例模式不要支持实例化,可能导致多个对象实例,也不要支持Icloneable接口,导致多个对象的实例,单例模式只考虑了对象创建的管理,没有考虑对象销毁的管理,支持垃圾回收的平台的对象的开销来讲,没必要对其销毁进行特殊的管理。

理解:Singleton模式核心:如何控制用户使用new对一个类的构造方法任意调用。

创建型模式篇(单例模式Single Pattern)的更多相关文章

  1. java架构之路-(设计模式)五种创建型模式之单例模式

    设计模式自身一直不是很了解,但其实我们时刻都在使用这些设计模式的,java有23种设计模式和6大原则. 设计模式是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可 ...

  2. 创建型模式篇(工厂模式Factory Pattern)

    一.工厂模式(Factory Pattern) 1.定义: 在软件系统,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口.提供一种封 ...

  3. Java设计模式(4)——创建型模式之单例模式(Singleton)

    一.概述 弥补一下之前没有给设计模式下的定义,先介绍一下设计模式(引用自百度百科): 设计模式(Design Pattern)是一套被反复使用.多数人知晓的.经过分类的.代码设计经验的总结. 使用设计 ...

  4. Python版设计模式: 创建型模式:单例模式和工厂模式家族

    一. 单例模式(Singleton) 所谓单例模式,也就是说不管什么时候都要确保只有一个对象实例存在.很多情况下,整个系统中只需要存在一个对象,所有的信息都从这个对象获取,比如系统的配置对象,或者是线 ...

  5. 创建型模式(一) 单例模式(Singleton)

    一.动机(Motivation) 在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性.以及良好的效率. 如何绕过常规的构造器,提供一种机制来保证一个类只 ...

  6. Java设计模式_创建型模式_单例模式

    单例模式的实现: 定义一个类,在类中定义该类的静态变量,再定一个一个获取该类的静态变量的方法. UML图:

  7. Java设计模式 - 单例模式(创建型模式)

    单例模式我在上学期看一些资料时候学习过,没想到这学期的软件体系结构就有设计模式学习,不过看似篇幅不大,介绍得比较简单,在这里我总结下单例模式,一来整理之前的笔记,二来也算是预习复习课程了. 概述 单例 ...

  8. Java 23种设计模式详尽分析与实例解析之一--创建型模式

    面向对象的设计原则 常用的面向对象设计原则包括7个,这些原则并不是独立存在的,它们相互依赖.互为补充. Java设计模式 创建型模式 简单工厂模式 模式动机: 考虑一个简单的软件应用场景,一个软件系统 ...

  9. php设计模式(一):简介及创建型模式

    我们分三篇文章来总结一下设计模式在PHP中的应用,这是第一篇创建型模式. 一.设计模式简介 首先我们来认识一下什么是设计模式: 设计模式是一套被反复使用.容易被他人理解的.可靠的代码设计经验的总结. ...

随机推荐

  1. python学习打卡 day07 set集合,深浅拷贝以及部分知识点补充

    本节的主要内容: 基础数据类型补充 set集合 深浅拷贝 主要内容: 一.基础数据类型补充 字符串: li = ["李嘉诚", "麻花藤", "⻩海峰 ...

  2. 【BZOJ】3142: [Hnoi2013]数列

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3142 12年也有一个组合数学...(这几年的画风啊.... 考虑直接去做:DP? DP+容 ...

  3. 【BZOJ】4542: [Hnoi2016]大数

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4542 给定一个由数字构成的字符串${S_{1,2,3,...,n}}$,一个正素数$P$, ...

  4. Systemd初始化进程/RHEL 6系统中System V init命令与RHEL 7系统中systemctl命令的对比

    Linux操作系统的开机过程是这样的,即从BIOS开始,然后进入Boot Loader,再加载系统内核,然后内核进行初始化,最后启动初始化进程.初始化进程作为Linux系统的第一个进程,它需要完成Li ...

  5. 如何将exe注册为windows服务,直接从后台运行

    方法一:使用windows自带的命令sc 使用sc create 方法创建. 如:注册服务 sc create ResharperServices binpath= D:\ResharperServi ...

  6. ppython的移位操作

    因为要将js的一个签名算法移植到python上,遇到一些麻烦. int无限宽度,不会溢出 算法中需要用到了32位int的溢出来参与运算,但是python的int是不会溢出的,达到界限后会自己转为lon ...

  7. sass、less是什么,如何使用?

    一个很好的介绍的SASS,LESS的区别的文档,值get 1.背景介绍 CSS 是一门非程序式语言,没有变量.函数.SCOPE(作用域),需要书写大量看似没有逻辑的代码,不方便维护及扩 展,不利于复用 ...

  8. git报错fatal: loose object ....(stored in .git/objects/....) is emtpy

    主要是非正常关机.把.git给破坏了 参考https://stackoverflow.com/questions/12571557/fixing-a-corrupt-loose-object-as-a ...

  9. 从flask视角学习angular(一)整体对比

    写在前面 前端框架完全不懂. 看着angular中文官网的英雄编辑器教程和核心知识,用偷懒的类比法,从flask django的角度 记录一下自己对angular的理解. 作为工科的武曲,自己的体会是 ...

  10. 通过TortoiseSVN进行文件(夹)外链 External File

    1.假设将server/a.lua文件外链到client文件夹中 2.在client文件夹空白处右键->TortoiseSVN->Properties->New->Extern ...