探討:為什麼在遊戲開發中不使用MVC?
來自專欄 Unity 遊戲開發總結152 人贊了文章
本篇文章我的觀點,部分來源於多年的項目實踐,部分源自和以前同事的討論,以及對一些系列文章和問答的閱讀。
正文開始前,先做一些聲明,因為這種類型的討論,必然導致很多反對。我只表明我個人的意見,說一點我的思考實踐,以及給出一些我看到的能支持我想法的論據。後續內容中,我可能對mvc或者當前的一些框架和設計方式提出一些批評,並不表明我是百分百堅定我的想法,也不表明我認為自己的想法絕對正確,做法最優。為了不在行文中,反覆需要表明我的不堅定,導致文章難以閱讀,故在此統一聲明,希望不要引起無謂的紛爭。
以下文章中,MVC泛指MVC,包括MVVM,MVP等MVC衍生的類似設計模式。
首先,我是用MVC的,在畢業早期開發應用軟體類程序,對不同數據的不同展示方式MVC是很好的設計。或者說,一個M(數據),多種V(展示),是應用軟體的常見展示方式,很適用MVC。大家在看Design pattern介紹MVC的時候,常用的例子,就是一個數據,即要餅狀圖展示,又要柱狀圖展示。
後來,轉行做頁游,覺得當時的項目,完全沒有什麼設計,胡亂堆砌,亂成一團,想起了MVC等設計模式,並且,還有很多人推薦的PureMVC,Robotleg等類MVC框架,並使用了依賴注入等模式,學習了demo之後,覺得很好地解決了遊戲設計問題。在跳槽後,在新的項目中,已經使用了robotleg,我進去後就很開心,開心地使用。真實地開發一段時間以後,我開始感覺到MVC或者說這類框架的問題(在和同事的討論中,也得到了牛逼同事很多提點),或者說,是使用者帶來的問題:
1,代碼繁冗,當你閱讀別人的代碼,一個很簡單的邏輯,被封裝了多次,需要在多個代碼文件中索引,閱讀效率極低。代碼文件分散,一些很簡單的邏輯,例如按鈕點擊,都做了多層封裝。
2,不太專業的某些程序的惰性,導致他們並不是真正理解MVC或者說這些框架的原理,他們的目標只是,把功能搞出來。他們要麼繞過框架,穿插了很多調用,要麼整體copy別人的一個功能,去掉邏輯,留下骨架,然後填充自己的邏輯,也不管這個骨架是否適用。這樣的人,大大增加了項目的混亂,leader要做到充分的代碼review,去除這些問題,在開發進度吃緊,每周都要出版本的情況下,是不可能的。這些快速堆出功能的程序員,反而得到策劃等非技術人員的讚賞。而認真處理,把每一塊都做好,但是慢一點的程序,反而不受誇獎,這導致了劣幣驅逐良幣。我相信,除了極少數精英團隊,很多團隊都有這樣的問題。
3,這些設計和框架,被濫用。比如MVC也許適用於UI部分的設計,但是,他是否適用一個戰鬥模塊呢?他是否適用一個劇情模塊呢?有些團隊,機械地運用某些框架,並不根據需求去思考,認為某個東西是好的,就到處使用。
當一個項目規模增長,人員難以保證精英,積累了大量的需求變更,運營期間,需要快速的迭代。這種繁雜冗餘的框架式設計,會導致代碼難以維護。有時候,並不是某個框架不夠好,更多的是,我們沒有仔細理清它的適用範圍,也難以保證規範從頭到尾的堅定執行。並留下大量過分設計的繁雜代碼,一個一百行,幾個funtion就能解決的問題,被包裝成了多個class,層層調用,寫了幾大百行,邏輯處處分散。
那麼,到底是某個框架,或者設計模式不行,還是我們使用得不夠好呢?
我們回到最初,仔細考慮,MVC解決的核心問題是,一個M,多個V,那麼,在遊戲領域,這樣的需求多嗎?是強需求嗎?我們到底應該根據需求來設計框架,還是應該根據框架來填充需求?一個框架,一套設計,適用不同的遊戲,不同的邏輯嗎?
我認真地考慮這塊問題,發現很多教程,文章,他們介紹MVC,MVVM,介紹各種框架,包括uframe,StrangeIoC等,都缺少了思考和提問:
- 這個框架適用什麼需求?解決了什麼問題?
- 在什麼情況下我該用,什麼情況不該用?他帶來了什麼問題?
- 是否適合我的項目,我的團隊?
- 我是應該項目整體使用,還是某些局部的需求使用呢?
等等問題,才是我們該問的關鍵。
我們遊戲領域的技術,特別是遊戲的框架,受到了太多應用軟體,web開發,app開發的影響,但是,這些模式並不適用我們啊!正式因為web,app這些領域的通用性,需求的固定性(相對遊戲開發而言),他們才會誕生出如此多的框架,模式,並且在技術領域,發出了更多的聲音。出現了看似高級的設計方式。並且,web,app的項目周期,以及後續的維護周期是很長的,少則三兩年,多則十幾年,確實必須要謹慎設計。但是,我們遊戲,特別是現在手游的生命周期又有多長呢?當需求不同,考慮問題的方式,解決問題的方式,應該做些改變。
想想《代碼大全2》開篇說的是什麼?隱喻,隱喻的重要性。這是全書的綱領啊,同志們。遊戲開發,和web,app開發,能歸為同一個隱喻嗎? 那麼我們問問自己:
- TDD適用我們遊戲前端開發嗎?
- WinForm的數據綁定,是適合我們遊戲開發的嗎?
- 幾十個設計模式,有幾個能適用我們遊戲開發的呢?分別對應什麼應用場景呢?
- 用Design pattern的目的,到底是design,還是去解決具體的問題?
當我們去追逐更新的設計,更酷的框架,我們有了解他們解決的問題嗎?我們有自己了解過他的原理嗎?到底在我們自己的項目中,他能解決什麼問題?我們有仔細思考過他在我們遊戲開發的整個生命周期,會給我們帶來什麼嗎?
最近,因為守望先鋒的一個分享,ECS開始火了起來。有個群里看到說,我們下個項目要上ECS了,問是什麼類型,答不知道,但是ECS這種先進框架,肯定要用。我只能說汗~~~
靜下心來,我也追求過最新的技術,最新的框架。但是,當我們真心開始做一個項目,去解決一些問題的時候,我們需要審慎。
比如ECS,我覺得雲風的說法,是最中肯的:
最終,我們要回到需求和問題,ECS,核心是為了解決網路同步中預測和預測失效的狀態回滾問題。如果你不是需要解決這類問題,你確定需要上ECS?一個回合制遊戲,確定需要ECS?UI寫法從MVC改ECS?
寫到這裡,說了那麼多批評的話,那麼,我認為什麼是最好的設計方式呢?
我認為,沒有最好的,只有根據需求來的,根據團隊能力來的,根據項目進度,經費來的,一切都要「具體問題,具體分析」。這句話,說出來輕鬆,做起來難,也有可能導致什麼都做不好,代碼更加混亂。那麼,只能根據團隊能力來選擇一個合適的開發方式,沒有最佳。
從MVC開始,說了那麼多,太多都是務虛的。但是,我認為務虛是很重要的,思考方式,方法論,都是很重要的。甚至,我們程序員學點哲學,也是大大有益。至少,讀讀笛卡爾的《談談方法》吧。
我們需要經驗慢慢積累,也需要慢慢對一些技術名詞去媚,沒有一招吃遍天。以下,我給出一些文章,也是一些我看到的,和我想法類似的東西,大家可以參看:
- Why are MVC & TDD not employed more in game architecture?
- Is the MVC design pattern used in commercial computer games
從第一篇能衍生出很多鏈接,都可以參看思考。
最後,我言辭可能略激烈,原因大家請參考前面的聲明。希望這篇務虛的思考和討論,能帶來一些不一樣的聲音。
-------------------------------------------------------------------------------------------
補充:
看了評論區里的一些評論,我覺得,我必須要說明一下:我寫這篇的目的,不是要告訴大家,設計不重要,框架不重要。我想明確的是:我們要仔細思考需求,來選擇合適的技術方案,而不是用在一個死板地框架里硬套需求。能夠審慎地選擇合適的設計方案,不盲從跟風。
但是,有些評論走向了另一個不看重設計的極端,情緒式的發泄,我認為是不妥的,更加有害的。本來,做任何一個設計,都需要試錯,根據需求的變更重構和改進,這當然需要時間成本,但是,這是我們的重要的個人成長之路,至少說明一個程序是看重自己的代碼的,重視自己的工作的。
大環境的問題,老闆的問題,或者leader的問題,進度緊的問題,當然是存在的客觀因素。但是這些客觀因素,不代表我們不能努力把事情做好,不代表我們不需要為自己的成長負責。如果因為客觀原因,混日子,隨便堆砌代碼,是對自己的不負責任吧。
行業開發進度緊,加班多,是一個非常不好的狀態,我對此也很不滿(之前加班痛苦時,甚至yy要組織個程序工會,汗~~)。但是我相信沒有一個人的工作是絕對長時間維持飽和的。我們總有時間聊聊qq,微信,上上網吧,那代表我們總有時間去思考怎麼把事情做得更好,只是個人選擇而已。
一個好的程序,會考慮當前需求,會預估一些需求的變化,給自己留些餘地,多少也會考慮,如果別人接手,是否能理順這個邏輯,後續變更大了,還會考慮去重構整理。甚至會站在用戶,玩家的角度,給策劃一些建議。這當然是知易行難的,所以,人和人,才有了區分,同樣的工作經驗,有的一兩年,就能做到很好,能獨當一面,有的5,6年後,混成了老油條。
總而言之,我這篇文章,是希望在認真對待工作和技術的情況下,更明智地思考和分析需求,選擇合適的設計或者實現方案。
虛無主義地吐槽,總是容易的。努力,總是伴隨著困難。
看,我也能寫點雞湯呢。
推薦閱讀: