私はシンプルなキューベースのシステムを使って複数のアクターに起こるイベントを管理するシステムを持っています。 Event
は、時間と抽象メソッドfire()
を持つ単純なクラスです。 Actor
は、think()
とact()
の2つのメソッドを実装するシンプルなインターフェイスです。一方で、Javaデザインパターン:イベントシステム、特定のアクターに対する複数のアクション
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
を生成することになっている、固定されている「思考」:各アクターは、そのように実装されている2つの基本的なイベントを、持っています「演技」の呼び出しは、アクションを実装するカスタムActorActEventベースのクラスを使用して行われ、費やされた時間だけが返され、新しい「思考」イベントが自動的にキューに追加されます。
私はここを参照してください問題がActorActEventベースのクラスの実装は、予め記憶された引数でActorActEvent.act()
からActor
クラスのいくつかのメソッドに、単純な委任に降りてくる、つまりすべての私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);
}
}
私は、このようなクラスが数十点あります。私が正しく理解していれば、それは古典的な実装のCommand patternです。しかし、私は、これらの委託クラスについてすべて気にしていません。特に、それらをすべて手動で書くことについては気にしません。
Method
インスタンスとあらかじめ格納されている引数を汎用ActorActEvent
クラスに渡しながら、JavaのリフレクションやものをMethod.invoke()のように使うと思っていましたが、かなり遅くなります。私はこれらすべてのクラスのジェネレータを書くことを考えましたが、それは私にとってかなり不器用な解決策のように見えます。
現代のスクリプト/関数型言語であれば、ブロック/クロージャーのような構造を使い、最初に準備して、時間が来たら呼び出すようにしましょう。ああ、私は効率的にJavaでそれを作る方法を知らない。
状況を改善するために何ができるのでしょうか?