Re: [請益] 程式設計一問

看板OOAD作者 (!H45)時間12年前 (2012/12/25 16:43), 編輯推噓1(100)
留言1則, 1人參與, 最新討論串2/2 (看更多)
※ 引述《NIKE74731 (耐吉七四七三一)》之銘言: : 各位好 : 當我們寫一個稍微大一點的類別時 : 通常因為功能較多 : 會切分成各個子系統進行操作,例如: : class BigSystem : { : private: : SystemA* m_pSysA; : SystemB* m_pSysB; : . : . : . : } : 既然是同一系統下的子系統 : 運作時當然會遇到必須使用到其它子系統的時候 : 例如 : class Game : { : private: : PlayerSystem* m_pPlayerSys; : EnemySystem* m_pEnemySys; : . : . : . : } : 以"當敵人死亡時,玩家生命值+10"為例 : EnemySystem::OnKilled() : { : //do something : //PlayerSystem.AddHP(10); : } : 問題就在如何執行PlayerSystem.AddHP(10)? : 直觀上我們可以有以下兩個方法 : 1.讓EnemySystem取得PlayerSystem,進而執行PlayerSystem的各項行為 : 2.在Game層寫個public的函式AddPlayerHP(int val),讓EnemySystem執行 : 但以上兩個方案都有一個相同的問題 : 開放了一個對Game類別外部來說 不需使用的介面 : 無論是Game::GetPlayerSystem()或者Game::AddPlayerHP() : 目的都是內部的操作 : 但卻將功能開放給外部 : 所以我想請問各位板友 : 對於這個情形來說 : 是否有解法? : 又或者說這樣的一個子系統設計方式本身就是有問題的? : 謝謝 PlayerSystem.AddHP(10) 本身就有問題吧? 並不是 PlayerSystem 增加 10 點 HP 而是 Player 增加 10 點 HP 應該是 Player.AddHP(10) 比較合理 最近我有些 Bukkit 插件開發的經驗 以 Bukkit 的設計而言 (下面所用的名稱可能和 Bukkit 有所不同,純舉例用) 「當敵人死亡時,玩家生命值+10」 程式流程是: 敵人死亡時,丟出一個「敵人死亡」事件 (EnemyDeathEvent) (此事件封裝著「敵人」物件與「玩家」物件) 類似觀察者模式 (Observer Pattern),看有沒有聆聽者 (EventListener) 要接這個事件 有的話就會通知對應的處理器 (Handler) 來處理 此例是玩家生命值+10 在該處理器內的回呼函式 (callback) 應接收該事件為函式輸入 然後在回呼函式內實作玩家生命值+10 類似下面這樣的寫法: class MyHandler implements EventListener { void callback(EnemyDeathEvent event) { Player player = event.getPlayer(); player.addHP(10); } } 到此算是做完了。 補充一點,在初始化聆聽者的部分 要在事件管理器 (EventManager) 登記處理器到相對應的事件上 如此才可在發生事件時,呼叫正確的處理器 類似下面這樣的寫法: void init() { EventManager manager = getEventManager(); EventListener handler = new MyHandler(); manager.registerEvent("EnemyDeathEvent", handler); } 到此初始化算是交代完了。 再補充關於 EventManager 的部分 這類別可以說是遊戲的事件系統 要判斷何時玩家殺掉敵人,然後要通知已登記的處理器 類似觀察者模式的主題(subject) 而 EventListener 則是觀察者。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.116.247.22

12/26 08:57, , 1F
推!!
12/26 08:57, 1F
文章代碼(AID): #1GsMSuIP (OOAD)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):
文章代碼(AID): #1GsMSuIP (OOAD)