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