關於遊戲中松耦合那些事……

本不想提這破事的,然而剛剛又看了篇類似的文章……那我就隨便提一嘴吧。

松耦合的優點大概如下:

1.便於在不修改任何代碼的情況下快速替換個別模塊。

2.可以達到完全互不干擾的並行開發。

3.可以做代碼隔離,每個開發人員只能獲得部分代碼,避免代碼泄露。

4.輕鬆編寫單元測試

5.極大加快編譯時間(實際工作中其實這個最重要= =)

因此,本著「有用才去用」的選擇,你的具體項目至少滿足以下其中一項,才有必要實行松耦合。

1.你的代碼有快速替換的需求。比如用於換皮遊戲,或者在編寫不定需求的公共庫(比如公共渠道接入模塊)。

2.在緊耦合的狀態下,並行開發遇到的問題已經妨礙到了開發效率。比如總不斷有人提交編譯錯誤的代碼上svn,或者總有坑貨一人在脫慢別人的進度,或者團隊成員之間拒絕交流和協調,以上問題的出現頻率和團隊人數成正比,和團隊素質成反比。

3.有做代碼隔離,而不是任何一個程序員都能打包帶走全套代碼,甚至把美術源文件和所有策劃文檔一併順走。考慮到unity反編譯的簡易性,遊戲還應該做了良好的混淆和加密。

4.有在編寫單元測試。

5.編譯真的很慢,而且不能用分層編譯的方式解決。

任何時候代碼都應該做分層(重用代碼),做約束(避免混亂),但這和是不是松耦合沒有半點關係。請不要因為框架常常在解耦的同時順便做這些事,就將它們混淆在一起。分層約束什麼的,你自己定就是了,也可以自寫耦合度較高的框架。大家基本都是這麼做的。

而松耦合的缺點是:

1.額外的工作量。這個不同框架情況不同,很多框架都在引入減少使用成本的功能,諸如依賴注入容器,也起到了良好的效果。這並不是重點。

2.減慢運行效率。除非是性能極度敏感的項目,這通常都不是問題。

3.不利於閱讀代碼。緊耦合的項目里讀到兩個模塊的連接部分,可以直接用f12跳轉到定義,或者查找引用,只需極少的時間和操作即能完成。而使用了消息通信的項目,你需要查找消息常量字元串以及一系列操作才可以完成。而假如你用了介面,而這個介面還真的對應了多個實現的話……

即使只有一個實現,也存在操作變得極度繁瑣的問題。這些問題還會隨著代碼隔離成為令人絕望的狀況。想要解決這個絕望的狀況,你需要更詳盡的介面文檔(因為不能不懂直接看實現),介面變更必須及時通知。由於平時不能進行聯調(你也不清楚對方有沒有完成),必須事先進行完備的模塊測試來減少模塊內錯誤,減少聯調時間,因為在這個狀況下,聯調的成本是極高的(因為不方便看對方代碼)

4.同上,並行開發變得容易的同時,也導致模塊間錯誤的發現變得困難了。「介面不統一」原本一件編譯期間就能發現並且立即定位的事,現在則成了一件需要編寫自動單元測試才能妥當解決的問題。

簡而言之,松耦合如果想達到緊耦合的代碼穩定性,單元測試是必要的。如果沒有,會有額外的可靠度隱患,也就是更多的bug,更多的修bug時間,更高的風險。

其實標準的松耦合就是前後端拆分。想想團隊里每個人都是用前後端的這種協作模式是個什麼鬼樣子吧。

一般傾向於,在大模塊中實行強耦合,然後根據上面提到的松耦合好處12345,根據情況將項目分成盡量少的大模塊,在它們之間實行松耦合,以便充分利用兩者的優點,迴避兩者的缺陷。

個人認為:4人以下,5w行代碼以下,這都屬於小項目。在小項目里搞松耦合通常都是弊大於利的。

超過這個量級可以考慮做一些處理,但都要適度。

而假如你的團隊有20個人,代碼要全耦合在一起的話……想想也不可能進行得下去吧?

說白了,遊戲項目之所以不興搞這套,主要的原因是遊戲項目實行的是少而精的團隊,而且基本都算得上是敏捷開發模式,本身模式就完全不同。實際的開發狀況(比如不做代碼隔離)也導致對松耦合的需求很低,其結果就是換來了同等質量下遠高於之前的開發效率,在目前快速出產品的思路下,開發效率才是第一位的。

而這也並沒有什麼不好吧?


推薦閱讀:

遊戲製作流程ver0.8
Gamejam 48小時極限遊戲創作指南[編輯中]
在GMS2中製作對話系統(2/2)
神谷英樹和他弟弟的遊戲回憶錄

TAG:編程 | 遊戲開發 |