Java设计模式: event system,给定参与者的多个操作

标签 java events design-patterns command queue

我有一个系统,它使用简单的基于队列的系统来管理多个参与者发生的事件。 Event 是一个简单的类,它有时间和一个抽象方法 fire()Actor 是一个简单的接口(interface),它实现了两个方法 - think()act()。每个参与者都有 2 个基本事件,其实现方式如下:

public class ActorThinkEvent extends Event {
    private Actor actor;

    public ActorThinkEvent(Actor actor, long time) {
        super(time);
        this.actor = actor;
    }

    public void fire() {
        Main.game.queue.add(actor.think());
    }
}
public abstract class ActorActEvent extends Event {
    protected Actor actor;

    protected ActorActEvent(Actor actor, long time) {
        super(time);
        this.actor = actor;
    }

    public void fire() {
        long spent = act();
        Main.game.queue.add(new ActorThinkEvent(actor, time + spent));
    }

    public abstract long act();
}

这样,“思考”调用就被修复了,它应该生成一个 ActorActEvent 并将其添加到全局队列中,而“行动”调用则使用基于自定义 ActorActEvent 的类来完成实现该操作,仅返回所花费的时间,并且新的“思考”事件将自动添加到队列中。

我在这里看到的问题是,基于 ActorActEvent 的类的实现归结为从 ActorActEvent.act() 到带有预定义的 Actor 类的某些方法的简单委托(delegate)存储的参数,即我的所有 ActEvent 类看起来都非常相似:

public class ActorMoveEvent extends ActorActEvent {
    private Coords delta;

    public ActorMoveEvent(Actor actor, long time, Coords delta) {
        super(actor, time);
        this.delta = delta;
    }

    public long act() {
        return actor.moveBy(delta);
    }
}
public class ActorReloadEvent extends ActorActEvent {
    public ActorReloadEvent(Actor actor, long time) {
        super(actor, time);
    }

    public long act() {
        return actor.reload();
    }
}
public class ActorPickupEvent extends ActorActEvent {
    private ItemStash wantedItems;

    public ActorPickupEvent(Actor actor, long time, ItemStash wantedItems) {
        super(actor, time);
        this.wantedItems = wantedItems;
    }

    public long act() {
        return actor.pickupItems(wantedItems);
    }
}

我可能最终会得到几十个这样的类(class)。如果我理解正确的话,这是 Command pattern 的经典实现。但是,我对所有这些委托(delegate)类感觉不太好,尤其是手动编写它们。

我想到使用Java的反射和诸如Method.invoke()之类的东西,但是,在通用 ActorActEvent 类中向其传递 Method 实例和预存储参数时,速度会相当慢。我想过为所有这些类编写一个生成器,但对我来说,它看起来是一个相当笨拙的解决方案。

如果它是某种现代脚本/函数式语言,我最终会使用类似 block /闭包的结构,首先准备它并在需要时调用它。唉,我不知道如何在 Java 中高效地实现它。

对于我能做些什么来改善这种情况有什么好主意吗?

最佳答案

我的建议是走反射(reflection)之路。在这种情况下,担心“速度会相当慢”还为时过早。反射的性能在过去十年中已经相当不错,您将能够缓存 Method 对象以节省重新解析名称所花费的时间(这可能是最大的性能损失)。这种方法实现起来灵活且快速。

如果您真的喜欢闭包,您可以为您的事件尝试匿名内部类。有一些限制 - 您仍然需要声明您的方法,因此它有点冗长,并且您需要将变量声明为 Final 以便从内部类中访问它们。这种方法将为您提供静态类型的所有性能和安全性,但您仍然必须为每个事件都有一个类。

从历史上看,事件表现出“两全其美”的行为,并在对象之间传递,依赖于目标知道如何转换和处理它们。

关于Java设计模式: event system,给定参与者的多个操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4642307/

相关文章:

java - OptaPlanner 车辆路线 - 车辆时间窗口

java - 服务中的冲水 session

c# - 在 C# 中声明事件的最佳实践

c# - 有没有比使用 Provider Factory 模式更简洁的解决方案?

delphi - Delphi 中的信号和槽实现?

java - 有大量参数的函数有什么解决方法吗?

java - 不满意链接错误 : no libhello in java. library.path

jquery显示ul li的数量

python - celery :事件==信号?

ruby-on-rails - Ruby 中可观察到的模式冗余