Unity C# 设计模式(一)单例模式
动机(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# 设计模式(一)单例模式的更多相关文章
- Unity3d设计模式之单例模式
单例模式我相信是所有设计模式之中运用最广泛的设计模式之一. 今天我们就来看看在unity中如何使用单例模式,在unity中,我们分两种单例,一种是继承monobehavior的单例,一种是普通单例. ...
- 设计模式之单例模式(Singleton)
设计模式之单例模式(Singleton) 设计模式是前辈的一些经验总结之后的精髓,学习设计模式可以针对不同的问题给出更加优雅的解答 单例模式可分为俩种:懒汉模式和饿汉模式.俩种模式分别有不同的优势和缺 ...
- GJM : C#设计模式(1)——单例模式
感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...
- java设计模式之单例模式(几种写法及比较)
概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...
- 每天一个设计模式-4 单例模式(Singleton)
每天一个设计模式-4 单例模式(Singleton) 1.实际生活的例子 有一天,你的自行车的某个螺丝钉松了,修车铺离你家比较远,而附近的五金店有卖扳手:因此,你决定去五金店买一个扳手,自己把螺丝钉固 ...
- 设计模式之单例模式的简单demo
/* * 设计模式之单例模式的简单demo */ class Single { /* * 创建一个本类对象. * 和get/set方法思想一样,类不能直接调用对象 * 所以用private限制权限 * ...
- 设计模式之单例模式——Singleton
设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...
- 10月27日PHP加载类、设计模式(单例模式和工厂模式)、面向对象的六大原则
加载类可以使用include.require.require_once三种中的任意一种,每个关键字都有两种方法,但是这种方法的缺点是需要加载多少个php文件,就要写多少个加载类的方法.一般也就需要加载 ...
- java 23 - 2 设计模式之单例模式
单例模式:保证类在内存中只有一个对象. 如何保证类在内存中只有一个对象呢? A:把构造方法私有 B:在成员位置自己创建一个对象 C:通过一个公共的方法提供访问 单例模式之饿汉式: (一进来就造对 ...
- [转]JAVA设计模式之单例模式
原文地址:http://blog.csdn.net/jason0539/article/details/23297037 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主 ...
随机推荐
- MyBatis数据持久化(七)多表连接查询
本节继续以多表连接查询的案例介绍使用resultMap的好处,对于两张以上的表进行关联查询,当我们有选择的从不同表查询所需字段时,使用resultMap是相当方便的.例如我们有两张表,分别为用户表Us ...
- [SHOI2012]魔法树
题目:洛谷P3833. 题目大意:给你一棵树,有两种操作:1.给两个点和它们之间的最短路上的所有点加上一个值:2.询问以某个点为根的子树的子树和.你需要实现这个功能. 解题思路:如果只有最后才询问的话 ...
- mysql 1067终极解决办法 亲测好使
进入mysql data 目录 删除 ib_logfile0 ib_logfile1 ibdata1 这三个文件 重启mysql
- 使用vuex的流程随笔
1.在建好的vue项目中新建一个vuex文件夹在此文件夹下建一个index.js文件,在此文件下引入vuex 模块(当然需要先npm下载)和vue模块,在引入你所有的自定义的module.js模块(下 ...
- svn文件管理器的使用
服务器端: 客户端 使用SVN的注意事项 做任何操作之前,先update一下 不要修改其他人的文件 不要在SVN里直接打开.编辑文件 不要在打开.编辑文件的时候,进行操作 SVN客户端的安装,非常简单 ...
- Uart,IIC和SPI的区别
1.UART, SPI, IIC的详解 UART.SPI.IIC是经常用到的几个数据传输标准,下面分别总结一下: UART(Universal Asynchronous Receive Transmi ...
- 2015 Multi-University Training Contest 3 hdu 5317 RGCDQ
RGCDQ Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- jsp-include 写法
被包含的页面: <%@ page language="java" import="java.util.*" pageEncoding="UTF- ...
- [android] 百度地图开发 (一).申请AK显示地图及解决显示空白网格问题
近期做android百度地图,可是使用baidumapapi_v2_3_1.jar和libBaiduMapSDK_v2_3_1.so显示百度地图时总是遇到问题--仅仅显示网格而没有显示地图,网 ...
- [MST] Store Store in Local Storage
For an optimal user and developer experience, storing state in local storage is often a must. In thi ...