Dependency Injection in Unity3D Part 3: DI v.s. MonoBehaviour-base

可能有人會覺得,Part 2開頭所描述的功能,用MonoBehaviour-base寫會快很多。
因此我在這一篇比較一下DI與MonoBehaviour-base在開發上的不同。

直接講結論,其實沒什麼不同

即使你使用MonoBehaviour-base來做開發,只要你致力於撰寫良好的程式碼,也仍然可以寫出良好的軟體架構。不過DI框架可以幫助你更容易寫出來。

MonoBehaviour的原生優勢與劣勢

在開發初期,MonoBehaviour-base開發速度的確比較快,而且真的挺快的。

MonoBehaviour與其它原生的Component類別,讓初學者比較容易上手。也讓從零開始的開發初期保持在幾乎無痛的狀態。在開發小規模的遊戲時,這個優勢十分明顯。在Game Jam或是開發遊戲雛形時,可以不用考慮撰寫良好程式碼時,MonoBehaviour為你創造很好的開發速度。

但為了其優勢所換來的問題,就如這一系列文章不斷提起的,是為了取得物件實體而大量使用singleton與繼承MonoBehaviour,寫出了高耦合性的程式碼,並進而衍生出的軟體架構問題。

在開發到一定規模時,只要架構稍有不佳,MonoBehaviour-base開發速度會開始急遽下降。

使用MonoBehaviour的原則

  1. 協助渲染的腳本,像是控制動畫的腳本、場景
    (透過SerializeField來獲取renderer或animator)
  2. 需要物理碰撞與觸發(透過OnCollision與OnTrigger系列函式)
  3. 需要使用coroutine的腳本(有時也可以用DI來解決)
  4. 其他與遊戲主邏輯無關的支援腳本,例如:FPS顯示、debug介面

Dependency Injection的優勢

使用DI的優勢在於,方便的獲取相依性
基於這個優勢,衍生出下面的好處。

1. 更容易寫出可測試的程式碼
我們都知道很難為MonoBehaviour寫測試,最主要的原因是難以透過介面來模擬與更換其相依物件。也就是說,很難為其注入相依性。

那麼注入相依性的工作就交給DI框架來處理吧!

2. 更加符合單一職責原則(Single Responsibility Prinsiple)
一般的狀況,尋找物件不外乎serialized field、GetComponent()或singleton。而且通常會寫在腳本的Awake()或Start()函式內。

藉由DI框架,尋找其它物件的職責就與本身的邏輯分離出來了。DI框架會負責提供相依性給物件。

3. 藉由上面2項優勢,你可以更加容易的切割出模組
你可以很容易的為單一模組創建出執行的環境。打個比方說,市面上主流的手機遊戲,總是有許多的系統,你可以很簡單的測試各個單一的系統。當設計師需要更換與移除系統時,你也可以無痛的進行修改。

4. 穩定的開發速度
你的程式碼不會再因為高耦合性衍生出問題,減少了解決衍生問題的時間,穩定了開發速度。

 

DI不是魔法,它只是一個手段,剛好解決了我們利用Unity開發遊戲時的根本問題。

下一篇文章會接續Part 2的功能,以進一步的例子來解釋如何調整遊戲參數、設定檔的注入、以及scriptable object的使用。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。