浅谈单例
程序员文章站
2022-05-17 16:14:30
单例模式 1.个人思路 1.业务需求 统一使用同一个对象(创建的对象为一个 使用的对象是同一个) 2.业务思考 3.实现的方案 2.保证生成的单例唯一 2.1 使用static让系统帮忙初始化 2.2 使用Unity的生命周期 2.3 使用锁保证单例唯一 2.4 使用字典保证生成的单例唯一 2.5 ......
单例模式
1.个人思路
- 1.业务需求
统一使用同一个对象(创建的对象为一个 使用的对象是同一个)
- 2.业务思考
- 如何生成对象 保存对象
- 如何保证生成的对象唯一
- 3.实现的方案
- 利用系统在需要用到对象前进行唯一 一次初始化
- 调用对象为空的时候 进行一次初始化 保存对象
2.保证生成的单例唯一
2.1 使用static让系统帮忙初始化
` public sealed class singleton { private static readonly singleton instance = new singleton(); private singleton() { } public static singleton instance { get { return instance; } } }`
2.2 使用unity的生命周期
` public sealed class singleton : monobehaviour { public static singleton instance { get; private set; } private void awake() { instance = this; } }`
2.3 使用锁保证单例唯一
` public sealed class singleton { private static singleton instance = null; private static readonly object syunclock = new object(); private singleton() { } public static singleton instance { get { if (instance == null) { lock (syunclock) { if (instance == null) { instance = new singleton(); } } } return instance; } } }`
2.4 使用字典保证生成的单例唯一
` public sealed class singleton : isingleton { private singleton() { } } public interface isingleton { } public class singletonmanager { private static readonly concurrentdictionary<string, isingleton> singletondict = new concurrentdictionary<string, isingleton>(); public static t getsingleton<t>() where t : class, isingleton { string classname = typeof(t).tostring(); if (!singletondict.containskey(classname)) { constructorinfo[] constructorinfos = typeof(t).getconstructors (bindingflags.instance | bindingflags.nonpublic); constructorinfo constructorinfo = array.find(constructorinfos, c => c.getparameters().length == 0); if (constructorinfo == null) { throw new exception("生成失败! 没有找到私有的构造函数"); } t manager = constructorinfo.invoke (null) as t; singletondict.tryadd(classname, manager); } return singletondict[classname] as t; } }`
2.5 综合考虑
` public class singletonmanager { private static gameobject singletonmanager; private static readonly object syunclock = new object(); private static readonly dictionary<string, isingleton> singletondict = new dictionary<string, isingleton>(); public static t getsingleton<t>() where t : class, isingleton { string classname = typeof(t).tostring(); if (!singletondict.containskey(classname)) { lock (syunclock) { if (!singletondict.containskey(classname)) { t manager = null; if (typeof(t).issubclassof(typeof(monobehaviour))) { addcomponentscript<t>(classname); } else { addscript(classname, manager); } } } } return singletondict[classname] as t; } private static void addcomponentscript<t>(string classname) { if(singletonmanager == null) { singletonmanager = new gameobject("singletonmanager"); unityengine.object.dontdestroyonload(singletonmanager); } type type = typeof(t); singletonmanager.addcomponent(type); singletondict.add(classname, singletonmanager.getcomponent(type) as isingleton); } private static void addscript<t>(string classname, t manager) where t : class, isingleton { constructorinfo[] constructorinfos = typeof(t).getconstructors(bindingflags.nonpublic | bindingflags.instance | bindingflags.declaredonly); constructorinfo constructorinfo = array.find(constructorinfos, c => c.getparameters().length == 0); if (constructorinfo == null) { throw new exception("生成失败! 没有找到私有的构造函数"); } manager = constructorinfo.invoke(null) as t; singletondict.add(classname, manager); } }` `public interface isingleton { }`