暑假期间总结了自己大一时学习了解的一些框架和写的小工具,顺便在这里回顾记录一下
GitHub工程文件网址:BlueSparkRain/GameFramwork (github.com)
泛型单例模式(Common/Singleton):
单例模式是unity游戏开发时不能错过(^-^真香)的工具类脚本
单例模式印象
单例模式反映了封装,分而治之的思想,便于开发者与团队间进行项目管理,将一段‘重复的功能代码’封装成一个独立的整体(如~Manager),从而实现部分功能代码的隔离,增强了代码的可读性与健壮性
单例模式基本定义
单例模式(Singleton Pattern)是 设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。单例模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。
为什么要使用泛型单例模式?
也许你的项目里现在已经有了很多单例脚本,在某一个瞬间,你忽然发觉自己写过单例脚本里的代码竟然是相同的,这时,深谙面向对象之道的你灵机一动,一拍脑门,哎!不妨让代码更优雅吧。
注意:泛型本身不是多态,泛型提供了一种类型安全的方式来编写可以处理多种数据类型的代码,而多态则允许对象以多种形式表现。泛型允许你在编译时指定类型,从而避免了运行时类型转换的问题。虽然泛型提供了类型参数化,但它仍然与类的多态性(如虚方法和接口实现)不同。
泛型单例模式的使用主要是为了实现一个可以被广泛复用的单例类,同时保留类型安全性和灵活性:
-
类型安全:泛型单例模式确保了返回的单例对象是指定的类型,而不是通用的
object
类型,从而避免了类型转换错误。 -
代码重用:泛型单例模式允许你创建不同类型的单例实例,而不需要为每种类型编写不同的单例类实现。这减少了代码重复,提高了维护性。
-
简洁性:通过使用泛型,你可以编写通用的单例实现代码,只需一次定义就能处理多种类型,使代码更加简洁和一致。
应用场景
在开发过程中经常将继承了泛型单例的基类的单例类脚本作为~Manager来使用,使声明单例的(通常情况下的)固定代码可复用
尝试实现
这里分享两种泛型单例模式的写法:
一种是不继承MonoBeheivor的BaseSingleton,另一种是继承了MonoBehevior的MonoSigleton
(这里的实现比较基础,实际使用的时依据实际情况进行修改即可)
BaseSingleton实现过程:
声明静态私有的T类型instnce变量 用于内部进行操作
声明静态公共T类型Instance属性 用于外部获取instnce变量
首次获取intance的时候new一个类对象
后续再次获取instance就直接返回之前的instance使用
实现代码:
/// <summary>
/// 单例模式基类 主要目的是避免代码的冗余 方便我们实现单例模式的类
/// </summary>
/// <typeparam name="T"></typeparam>
public class BaseSingletonManager<T> where T : class
{
private static T instance;
//属性的方式
public static T Instance
{
get
{
if (instance == null)
{
if (instance == null)
{
instance = new T();
}
}
return instance;
}
private set { }
}
}
MonoSingleton实现过程:
声明静态私有的T类型instnce变量 用于内部进行操作
声明静态公共T类型Instance属性 用于外部获取instnce变量
做了MonoSingleton在获取instnce时的流程图:
实现代码:
/// <summary>
/// 自动挂载式的继承Mono的单例脚本基类,推荐使用,无需手动挂载,无需考虑切场问题,动态添加,
/// 尽量不要手动挂载
/// </summary>
/// <typeparam name="T"></typeparam>
[DisallowMultipleComponent]//禁止在同一个gamobject上挂载多个相同此脚本
public class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
private static T instance;
public static T Instance
{
get
{
if (instance == null)
{
//手动挂载式
instance = FindAnyObjectByType<T>();
//自动挂载式
if (instance == null)
{
//非挂载式单例在被调用时直接创建
GameObject newManager=new GameObject(typeof(T) + "SingleManager");
instance = newManager.AddComponent<T>();
instance.Init(newManager);
DontDestroyOnLoad(newManager);
}
}
return instance;
}
private set { }
}
protected virtual void Awake()
{
if (instance != null)
{
Destroy(this);
return;
}
//手动挂载式初始化
if (instance == null)
{
instance = this as T;
}
DontDestroyOnLoad (this.gameObject);
}
public virtual void Init(GameObject newManager)
{
//实际使用时的初始化代码
}
}
本篇完