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

作者: H45 (!H45)   2012-12-25 16:43:34
※ 引述《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 則是觀察者。

Links booklink

Contact Us: admin [ a t ] ucptt.com