之前的文章中介紹的 《Unity 游戲框架搭建 (二) 單例的模板》 和 《Unity 游戲框架搭建 (三) MonoBehaviour單例的模板》有一些問題。
## 存在的問題:
* 只要繼承了單例的模板就無法再繼承其他的類。
雖然單例繼承其他類是比較臟的設計,但是難免會遇到不得不繼承的時候。沒有最好的設計,只有最合適的設計。
## 解決方案:
* 首先實現單例的類從使用方式上應該不變,還是
```cs
XXX.Instance.ABCFunc()
```
之前的單利的模板代碼如下所示:
```cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
/// <summary>
/// 1.泛型
/// 2.反射
/// 3.抽象類
/// 4.命名空間
/// </summary>
namespace QFramework {
public abstract class QSingleton<T> where T : QSingleton<T>
{
protected static T mInstance = null;
protected QSingleton()
{
}
public static T Instance
{
get {
if (mInstance == null) {
// 先獲取所有非public的構造方法
ConstructorInfo[] ctors = typeof(T).GetConstructors (BindingFlags.Instance | BindingFlags.NonPublic);
// 從ctors中獲取無參的構造方法
ConstructorInfo ctor = Array.Find (ctors, c => c.GetParameters ().Length == 0);
if (ctor == null)
throw new Exception ("Non-public ctor() not found!");
// 調用構造方法
mInstance = ctor.Invoke (null) as T;
}
return mInstance;
}
}
public void Dispose()
{
mInstance = null;
}
}
}
```
按照以前的方式,如果想實現一個單例的代碼應該是這樣的:
```cs
using QFramework;
// 1.需要繼承QSingleton。
// 2.需要實現非public的構造方法。
public class XXXManager : QSingleton<XXXManager>
{
private XXXManager()
{
// to do ...
}
}
public static void main(string[] args)
{
XXXManager.Instance().xxxyyyzzz();
}
```
如果我想XXXManager繼承一個BaseManager代碼就變成這樣了
```cs
using QFramework;
// 1.需要繼承QSingleton。
// 2.需要實現非public的構造方法。
public class XXXManager : BaseManager
{
private XXXManager()
{
// to do ...
}
}
public static void main(string[] args)
{
XXXManager.Instance().xxxyyyzzz();
}
```
這樣這個類就不是單例了,怎么辦?
答案是通過 C# 的屬性。
```cs
using QFramework;
// 1.需要繼承QSingleton。
// 2.需要實現非public的構造方法。
public class XXXManager : BaseManager
{
private XXXManager()
{
// to do ...
}
public static XXXManager Instance
{
get
{
return QSingletonComponent<XXXManager>.Instance;
}
}
}
public static void main(string[] args)
{
XXXManager.Instance().xxxyyyzzz();
}
```
好了,又看到陌生的東西了,QSingletonComponent 是什么?
和之前的單例的模板很相似,貼上代碼自己品吧...
```cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
/// <summary>
/// 組合方式實現單例子
/// </summary>
namespace QFramework
{
/// <summary>
/// class是引用類型
/// </summary>
public class QSingletonComponent<T> where T : class
{
protected static T mInstance = null;
public static T Instance
{
get
{
if (mInstance == null)
{
// 先獲取所有非public的構造方法
ConstructorInfo[] ctors = typeof(T).GetConstructors (BindingFlags.Instance | BindingFlags.NonPublic);
// 從ctors中獲取無參的構造方法
ConstructorInfo ctor = Array.Find (ctors, c => c.GetParameters ().Length == 0);
if (ctor == null)
throw new Exception ("Non-public ctor() not found!");
// 調用構造方法
mInstance = ctor.Invoke (null) as T;
}
return mInstance;
}
}
public static void Dispose()
{
mInstance = null;
}
}
}
```
這樣無法繼承的問題就解決啦。
缺點是:
* 相比于 QSingleton,QSingletonComponent 在使用時候多了一次函數調用,不過做中小型項目應該可以應付了。
介紹完畢,睡覺了。。。
## 歡迎討論!
轉載請注明地址:涼鞋的筆記:[liangxiegame.com](http://liangxiegame.com)
## 更多內容
* QFramework 地址:[https://github.com/liangxiegame/QFramework](https://github.com/liangxiegame/QFramework)
* QQ 交流群:[623597263](http://shang.qq.com/wpa/qunwpa?idkey=706b8eef0fff3fe4be9ce27c8702ad7d8cc1bceabe3b7c0430ec9559b3a9ce66)
* **Unity 進階小班**:
* 主要訓練內容:
* 框架搭建訓練(第一年)
* 跟著案例學 Shader(第一年)
* 副業的孵化(第二年、第三年)
* 權益、授課形式等具體詳情請查看[《小班產品手冊》](https://liangxiegame.com/master/intro):https://liangxiegame.com/master/intro
* 關注公眾號:liangxiegame 獲取第一時間更新通知及更多的免費內容。

- 正文
- Unity 游戲框架搭建 2017(一)概述
- Unity 游戲框架搭建 2017(二)單例的模板
- Unity 游戲框架搭建 2017(三)MonoBehaviour 單例的模板
- Unity 游戲框架搭建 2017(四)簡易有限狀態機
- Unity 游戲框架搭建 2017(五)簡易消息機制
- Unity 游戲框架搭建 2017 (六) 關于框架的一些好文和一些思考
- Unity 游戲框架搭建 2017 (七) 減少加班利器-QApp類
- Unity 游戲框架搭建 2017 (八) 減少加班利器-QLog
- Unity 游戲框架搭建 2017 (九) 減少加班利器-QConsole
- Unity 游戲框架搭建 2017 (十) QFramework v0.0.2小結
- Unity 游戲框架搭建 2017 (十一) 簡易 AssetBundle 打包工具 (一)
- Unity 游戲框架搭建 2017 (十二) 簡易 AssetBundle 打包工具 (二)
- Unity 游戲框架搭建 2017 (十三) 無需繼承的單例的模板
- Unity 游戲框架搭建 2017 (十四) 優雅的 QSingleton (零) QuickStart
- Unity 游戲框架搭建 2017 (十四) 優雅的 QSingleton (一) Singleton 單例實現
- Unity 游戲框架搭建 2017 (十四) 優雅的 QSingleton (二) MonoSingleton單例實現
- Unity 游戲框架搭建 2017 (十四) 優雅的 QSignleton (三) 通過屬性器實現 Singleton
- Unity 游戲框架搭建 2017 (十四) 優雅的 QSingleton (四) 屬性器實現 Mono 單例
- Unity 游戲框架搭建 2017 (十四) 優雅的 QSingleton (五) 優雅地進行GameObject命名
- Unity 游戲框架搭建 2017 (十五) 優雅的 QChain (零)
- Unity 游戲框架搭建 2017 (十六) v0.0.3 架構調整
- Unity 游戲框架搭建 2017 (十七) 靜態擴展GameObject 實現鏈式編程
- Unity 游戲框架搭建 2017 (十八) 靜態擴展 + 泛型實現 transform 的鏈式編程
- Unity 游戲框架搭建 2017 (十九) 簡易對象池
- Unity 游戲框架搭建 2017 (二十) 安全的對象池
- Unity 游戲框架搭建 2017 (二十一) 使用對象池時的一些細節
- Unity 游戲框架搭建 2017 (二十二) 簡易引用計數器
- Unity 游戲框架搭建 2017 (二十三) 重構小工具 Platform
- Unity 游戲框架搭建 2017 (二十四) 小結