动机(Motivation):
    在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率

意图:
    保证一个类仅有一个实例,并提供一个访问它的全局访问点。

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

代码实现:
(1)单线程Singleton实现

/// <summary>
/// 单例类
/// </summary>
public class SingleThread_Singleton_Class { //静态属性,提供全局访问点
private static SingleThread_Singleton_Class instance=null;
public static SingleThread_Singleton_Class Instance
{
get{
if (instance==null) {
instance = new SingleThread_Singleton_Class ();
}
return instance;
}
}
//私有的构造函数保证该类不能在其他类里实例化,即不能在其他类里new
private SingleThread_Singleton_Class(){} //用于单例测试
public void Print()
{
UnityEngine.Debug.Log ("我是单例类");
}
}

以上代码在单线程情况下不会出现任何问题。但是在多线程的情况下却不是安全的。
如两个线程同时运行到 if (instance == null)判断是否被实例化,一个线程判断为True后,在进行创建
 instance = new SingleThread_Singleton();之前,另一个线程也判断(instance == null),结果也为True.
这样就就违背了Singleton模式的原则(保证一个类仅有一个实例)。
怎样在多线程情况下实现Singleton?

(2)多线程Singleton实现:

public class MultiThread_Singleton {

    private static volatile MultiThread_Singleton instance=null;
private static object locker=new object();
private MultiThread_Singleton (){}
public static MultiThread_Singleton Instance
{
get{
if (instance==null) {
lock (locker) {
if (instance==null) {
instance = new MultiThread_Singleton ();
}
}
}
return instance;
}
} private int i=;
public void Print()
{
i++;
UnityEngine.Debug.Log ("第 "+i+" 次打印");
}
}

此程序对多线程是安全的,使用了一个辅助对象locker,保证只有一个线程创建实例(如果instance为空,保证只有一个线程instance = new MultiThread_Singleton();创建唯一的一个实例)。(Double Check)
请注意一个关键字volatile,如果去掉这个关键字,还是有可能发生线程不是安全的。
volatile 保证严格意义的多线程编译器在代码编译时对指令不进行微调。

(3)静态Singleton实现

public class Static_Singleton {
public static readonly Static_Singleton Instance = new Static_Singleton ();
private Static_Singleton() {
} public void Print()
{
Debug.Log ("我是静态单例");
}
}

优点: 简洁,易懂
缺点: 不可以实现带参数实例的创建。

(4)Unity Singleton脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 单例脚本
/// </summary>
public class SingleThread_Singleton_Script : MonoBehaviour {
private SingleThread_Singleton_Script(){}
public static SingleThread_Singleton_Script instance;
void Awake()
{
instance = this;//初始化
} public void Print()
{
Debug.Log ("我是单例脚本");
}
}

风险:

1、外部类依然可以同过GetComponent<>的形式实例化出该对象。

2、当单例脚本一旦被初始化后,即当程序运行后,从场景中去掉单例脚本组件,还是可以会执行该类的相关方法

Unity C# 设计模式(一)单例模式的更多相关文章

  1. Unity3d设计模式之单例模式

    单例模式我相信是所有设计模式之中运用最广泛的设计模式之一. 今天我们就来看看在unity中如何使用单例模式,在unity中,我们分两种单例,一种是继承monobehavior的单例,一种是普通单例. ...

  2. 设计模式之单例模式(Singleton)

    设计模式之单例模式(Singleton) 设计模式是前辈的一些经验总结之后的精髓,学习设计模式可以针对不同的问题给出更加优雅的解答 单例模式可分为俩种:懒汉模式和饿汉模式.俩种模式分别有不同的优势和缺 ...

  3. GJM : C#设计模式(1)——单例模式

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  4. java设计模式之单例模式(几种写法及比较)

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

  5. 每天一个设计模式-4 单例模式(Singleton)

    每天一个设计模式-4 单例模式(Singleton) 1.实际生活的例子 有一天,你的自行车的某个螺丝钉松了,修车铺离你家比较远,而附近的五金店有卖扳手:因此,你决定去五金店买一个扳手,自己把螺丝钉固 ...

  6. 设计模式之单例模式的简单demo

    /* * 设计模式之单例模式的简单demo */ class Single { /* * 创建一个本类对象. * 和get/set方法思想一样,类不能直接调用对象 * 所以用private限制权限 * ...

  7. 设计模式之单例模式——Singleton

                        设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...

  8. 10月27日PHP加载类、设计模式(单例模式和工厂模式)、面向对象的六大原则

    加载类可以使用include.require.require_once三种中的任意一种,每个关键字都有两种方法,但是这种方法的缺点是需要加载多少个php文件,就要写多少个加载类的方法.一般也就需要加载 ...

  9. java 23 - 2 设计模式之单例模式

    单例模式:保证类在内存中只有一个对象. 如何保证类在内存中只有一个对象呢?  A:把构造方法私有  B:在成员位置自己创建一个对象  C:通过一个公共的方法提供访问 单例模式之饿汉式: (一进来就造对 ...

  10. [转]JAVA设计模式之单例模式

    原文地址:http://blog.csdn.net/jason0539/article/details/23297037 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主 ...

随机推荐

  1. 使用JS方法使页面滚动到指定元素+优化+API介绍(动画)

    前言 当页面最上部有顶部菜单是,使用锚点跳转的方法很容易挡住想要呈现的内容(如下图技能两个字被挡住了一半),为避免出现这样的问题,故滚动到指定元素使用用JS的方法来实现. 目录 使用的API简介 初版 ...

  2. AOJ GRL_1_C: All Pairs Shortest Path (Floyd-Warshall算法求任意两点间的最短路径)(Bellman-Ford算法判断负圈)

    题目链接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_C All Pairs Shortest Path Input ...

  3. ActiveMQ学习笔记(13)----Destination高级特性(一)

    1. Wildcards 1. Wildcards用来支持名字分层体系,它不是JMS规范的一部分,是ActiveMQ的扩展. ActiveMQ支持一下三种wildcards: 1. ".&q ...

  4. 比较好的Dapper封装的仓储实现类 来源:https://www.cnblogs.com/liuchang/articles/4220671.html

    using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; usin ...

  5. (三)React基础

    3-1 使用React编写TodoList功能 import { Fragment} from ‘react’ Fragment是占位符 用于替代最外层div元素, 防止生成的元素会有两层div嵌套这 ...

  6. Keepalived原理及VRRP协议与应用配置(详细)

    转载自:https://blog.csdn.net/u010391029/article/details/48311699 1. 前言 VRRP(Virtual Router Redundancy P ...

  7. numpy学习笔记 - numpy数组的常见用法

    # -*- coding: utf-8 -*- """ 主要记录代码,相关说明采用注释形势,供日常总结.查阅使用,不定时更新. Created on Mon Aug 20 ...

  8. [MST] Create an Entry Form to Add Models to the State Tree

    It is time to add new entries to the wishlist. We will achieve this by reusing forms and models we'v ...

  9. 50个Android开发技巧(09 避免用EditText对日期进行验证)

    我们都知道,在表单中对数据进行验证不但无聊并且easy出错. (原文地址:http://blog.csdn.net/vector_yi/article/details/24424713) 想象一下,一 ...

  10. SPFA的两种优化

    SPFA是可以优化的,这个大家都是晓得的吧. 下面介绍两种SPFA的神奇优化(我只代码实现了的一种) SLF:Small Label First策略,设要加入的节点是j,队首元素为i,若dist(j) ...