淺談游戲開發中常見的設計模式

来源:https://www.cnblogs.com/jason-koo/archive/2019/06/18/11042283.html
-Advertisement-
Play Games

前言 因為游戲開發在架構上要考慮性能和實際需求,在儘量不引入第三方庫、框架的前提下進行開發,所以在編碼時候會經常用到設計模式對代碼進行復用,對業務邏輯架構解耦,儘量減少hard code。 單例模式(Singleton Pattern) 單例模式經常會用在邏輯上唯一的對象(通常用於重量級資源)上,如 ...


前言  

因為游戲開發在架構上要考慮性能和實際需求,在儘量不引入第三方庫、框架的前提下進行開發,所以在編碼時候會經常用到設計模式對代碼進行復用,對業務邏輯架構解耦,儘量減少hard code。

單例模式(Singleton Pattern)

單例模式經常會用在邏輯上唯一的對象(通常用於重量級資源)上,如Factory、Context、Resource、Pool和Service等,但在代碼細節上需要註意開放出去的介面以及該介面的嚴格語義。單例模式通常帶有生命周期函數,有利於結合框架自己的生命周期管理進行初始化或銷毀操作。在開發過程中會遇到一些不好的例子,如變數都是類靜態成員變數、方法都是靜態方法,這樣寫的代碼可能在調用上的結果符合“單例”這個語義,但是會讓其他人感到困惑。

工廠模式(Factory Pattern)

使用工廠模式來統一創建對象有利於管理對象的生命周期,通常會組合單例模式、代理模式、策略模式,對複雜的對象進行組裝,對創建的對象進行統一管理。統一對象入口的好處在開發初期可能不明顯,但隨著開發進度的推動,業務的越來越複雜,統一入口容易更好地跟蹤對象的生命周期,也容易的對某類對象初始化時進行統一的操作。

策略模式(Strategy Pattern)

對於一些邏輯相似但實現的細節不同粒度又比較細的業務,可以將保證語義粒度適中的介面提取出來,按不同的實現邏輯來封裝成不同的策略,在通過策略容器(通常是工廠容器)在上層業務中進行組合調用。這樣既可以保證邏輯結構的清晰又便於擴展。在游戲開發中,狀態機就是一個使用策略模式的例子,狀態機本身就是一個策略容器,它將與狀態相關的行為從大量的跳轉中抽離處理,讓代碼結構更清晰明瞭。代碼結構越清晰,跳轉越少意味著出現BUG機率越低,調試起來更容易。個人覺得策略模式的關註點應該在介面的粒度上,它跟代理模式不同,要求粒度適中,根據具體的業務去動態選擇策略使得封裝的代碼脫離於客戶代碼。使用策略模式來解耦代碼是一個很好的選擇。

代理模式(Proxy Pattern)

代理模式跟策略模式其實很相似,粒度比策略模式粗,用於控制訪問對象。舉個例子,有一個複雜的數據對象有一個通用的二進位序列化介面,因為業務擴大,序列化數據越來越大,而網路層限制了協議的最大長度。這時是需要改網路底層?把公共的序列化介面改掉?還是在調用的代碼上hard code一次裁剪後的序列化代碼?答案是顯而易見的:只需要一個面對這個協議的對象訪問器,而這個訪問器只需要根據業務實現裁剪後的序列化介面。使用代理模式,更好的保護對象的封裝,讓頻繁改變的業務跟穩定的對象隔離開來。

觀察者模式(Observer Pattern)/訂閱發佈模式(Subscribe/Publish)

這兩個模式主要為瞭解耦獨立對象間的耦合,在這裡放在一起來講,因為這兩個模式主要區別在結構上,觀察者模式是直接耦合的,發佈訂閱模式是鬆散耦合的。在游戲開發上中經常看到XXXListener,這就是用了這兩個模式(大多數用訂閱發佈模式)。在游戲開發中,除了框架提供的事件生命周期外,其實可以用這些模式去鬆散具體業務的耦合。舉個例子,在一個複雜的養成系統上有很多條養成線,養成線互相有勾連,養成線的變動除了系統與角色的交互操作外,其他的養成線的交互操作應該只停留在這個養成系統本身,這時候就需要觀察者模式/發佈訂閱模式將這些養成線的交互隔離開來。

模板模式(Template Pattern)

這個模式偏向於框架編程,在實際開發中需要考慮到common——domain的比重,在考慮實際需要的抽象程度和業務的粒度。抽象程度太高會導致開發效率降低和實現難度增大,抽象程度太低又會導致業務性太強以致不好擴展和維護,這是一個值得深思的問題。

組合模式(Composite Pattern)

面向對象最重要的復用方式多態和組合,組合模式將不穩定的對象隔離,以樹狀結構連接起來。使用組合模式的好處是頻繁改動的部分不會影響到穩定的整體,但缺點是不能使用多態這個語法糖來進行直接復用。在開發中嚴謹地使用組合模式和繼承會讓代碼結構清晰和更從容面對業務地變更。關註點在於變的部分,就像陰陽兩極一樣,在實際開發中怎麼用組合/繼承也是一個值得深思的問題。

後話

其實還有很多設計模式我沒有提到,因為我的實際開發場景很少遇到。我認為,設計模式是死的,而業務是活的。按照《Clean Architecture》中Bob大叔介紹的軟體設計原則,再結合實際加以運用,不斷地提煉代碼,相信你也會發現編碼的樂趣。本人拙見,謹在此拋磚引玉。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、瀏覽器介紹 瀏覽器是網頁運行的平臺,常用的瀏覽器有 IE、火狐(Firefox)、谷歌(Chrome)、Safari和Opera等。我們平時稱為五大瀏覽器。 可以通過這個網址 http://tongji.baidu.com/data/browser 查看瀏覽器的占有的市場份額 二、瀏覽器內核 1 ...
  • [2019.06.19 學習筆記4] 1.標簽格式 <開始標簽></結束標簽> 不區分大小寫,而且規則寬鬆。推薦小寫,並且要求成對編寫。 2.閉合標簽 <h1>內容</h1> 3.自閉合標簽(沒有內容的標簽) <img/> ...
  • 技術人員在構思一項功能時,會同時在大腦中編織其實現細節! 不利的一面 這種編織過程就像本能難以避免,它有優勢,對現實可行性更有判斷,但不利的影響也很明顯! 1、容易陷入細節,破壞思維的整體性。 2、構思的實現複雜度會直接影響決策。 這種構思本身受個人經驗所限。事實上實際複雜度有不確定性,再加上複雜度 ...
  • 今天,早早的起床,被外面火辣辣的太陽曬紅了臉。洗漱完發現已經遲到了,又不能吃早餐,來到了教室,面對著操蛋的課程,很令人蛋疼。啊,,,,美好的一上午就這麼結束了。 ...
  • 本章描述了團隊為準備Contoso會議管理系統的第一個產品版本所做的更改。這項工作包括對前兩章介紹的訂單(Order)和註冊(Registrations)限界上下文的一些重構和功能添加,以及一個新的會議管理(Conference Management)限界上下文和一個新的支付(Payment)限界上... ...
  • [toc] 基於Coravel定時任務之計算總頁數 1 應用背景 在物聯網系統中,需要計算底端所有設備的總數,除以分頁每頁顯示數量,進行一個總頁數的顯示。包括狀態,告警,日誌等等數據都需要對應的總頁數的顯示。 2 對比各家定時庫 2.1 TaskScheduler TaskScheduler庫只支持 ...
  • Shuffle輸出追蹤者 MapOutputTracker 這個組件作為shuffle的一個輔助組件,在整個shuffle模塊中具有很重要的作用。我們在前面一系列的分析中,或多或少都會提到這個組件,比如在DAGScheduler提交一個stage時會將這個stage封裝成一個任務集(TaskSet) ...
  • 在空對象模式(Null Object Pattern)中,一個空對象取代 NULL 對象實例的檢查。Null 對象不是檢查空值,而是反應一個不做任何動作的關係。這樣的 Null 對象也可以在數據不可用的時候提供預設的行為。 AbstractObject.m RealObject.m NullObje ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...