我正在开发一个小型游戏模板,其世界由如下节点组成:
World
|--Zone
|----Cell
|------Actor
|------Actor
|--------Item
Where a World
可以包含多个Zone
物体,一个Zone
可以包含多个Cell
对象等。
其中每一个都实现了Node
接口,其中有一些方法,例如getParent
, getChildren
, update
, reset
等等。
我希望能够执行给定的Task
在单个节点上或从节点递归地沿着树向下(由Task
).
为了解决这个问题,我希望这是一个“可插入”系统,这意味着我希望玩家/开发人员能够动态向树中添加新类型。我还考虑过从基本类型进行转换:
public void doTask(Actor node)
{
if(!(node instanceof Goblin)) { return; }
Goblin goblin = (Goblin) node;
}
最初我被吸引使用访客模式 https://en.wikipedia.org/wiki/Visitor_pattern利用双重调度,允许每个例程(访问者)根据访问者的类型进行操作Node
被访问。然而,这导致了一些并发症,特别是当我想添加一个新的Node
键入树。
作为替代方案,我写了一个实用类 https://github.com/floralvikings/jenjin/blob/node-overhaul/jenjin-world-core/src/main/java/com/jenjinstudios/world/reflection/DynamicMethodSelector.java它使用反射来查找适用于的最具体的方法Node
.
我现在关心的是性能 https://stackoverflow.com/questions/435553/java-reflection-performance;由于将会有相当大量的反射查找和调用,我担心我的游戏的性能(每秒可能有数百或数千个此类调用)会受到影响。
这似乎解决了两种模式的问题,但使每个新的代码Task
uglier.
在我看来,我有三个选项来允许这种动态调度(除非我错过了一些明显/模糊的东西,这就是我在这里的原因):
- Visitor Pattern
- Pros
- Cons
- 很难添加新的
Node
类型(不修改原始代码是不可能的)
- 任务调用期间的丑陋代码
- Dynamic Invocation using Reflection
- Pros
- 可以添加新的
Node
放弃类型
- 非常可定制的任务
- 任务中的整洁代码
- Cons
- Casting
- Pros
- 比反射性能更高
- 可能比访客更有活力
- 任务调用期间干净的代码
- Cons
- 代码气味
- 性能低于 Visitor(没有双重调度,每次调用都进行强制转换)
- 任务中的丑陋代码
我在这里错过了一些明显的事情吗?我熟悉“四人帮”的许多模式,以及《四人帮》中的模式。游戏编程模式 http://gameprogrammingpatterns.com/。任何帮助将不胜感激。
需要明确的是,我并不是在问其中哪一个是“最好的”。我正在寻找这些方法的替代方案。