1

この質問は、ここにある委任設計パターンに関するものです。

さまざまなエンティティを表すゲーム エンジン用のインターフェイスが多数あります。

  • プレーヤー
  • 車両
  • メッシュ

これらはそれぞれレンダリングできるため、メソッドを含む Renderable インターフェイスを実装しますrender()

方法 1

委任を使用すると、例は次のようになります。

public interface Vehicle {

    public void drive();

}

public class Car implements Vehicle {

    public Renderable renderable;

    @Override
    public void drive() { // ... }

}

車をレンダリングしたいときはいつでも、 を呼び出すだけcar.renderable.render();です。

この方法の問題は、リストを作成して反復処理できないことです。

方法 2

これを解決するために、Vehicle を Renderable に拡張することができます。

public interface Vehicle extends Renderable {

    public void drive();

}

しかし、これの問題は、Car、Bicycle、Truck、Tank などを定義すると、これらのクラスのそれぞれに render() のコードを入力する必要があることです (これはおそらく同一です)。

Vehicle を実装するすべての具象クラスで render() を定義せずに、Vehicle インターフェイスで Renderable を拡張する利点を維持する方法はありますか?

4

3 に答える 3

2

私のコメントについては、

Renderableを保持する各クラスには、パブリックRenderable getRenderable()メソッドがありますか?もしそうなら、これをあなたがこれらの獣のコレクションを保持することを可能にするインターフェースにすることができませんでしたか?

私はこのようなことを意味していました:

interface Renderable {
   void render();
}

interface RenderDelegator {
   Renderable getRenderable();
   void setRenderable(Renderable renderable);
}

abstract class Vehicle implements RenderDelegator {
   private Renderable renderable;

   @Override
   public Renderable getRenderable() {
      return renderable;
   }

   @Override
   public void setRenderable(Renderable renderable) {
      this.renderable = renderable;
   }

   public abstract void drive();
}

class Car extends Vehicle {
   @Override
   public void drive() {
      // TODO finish!
   }

}

そして、Iterableの実装についてのその提案をnixします。何を考えていたのかわかりません。

于 2013-01-14T22:40:08.337 に答える
1

もう 1 つのアプローチは、Renderable オブジェクトの概念をその可能なデリゲート レンダラーから分離することです。このように、レンダラー コードが単一のクラスに固有である場合は、一般的なレンダラーに委譲するか、render() メソッドをクラスに直接実装するかを選択できます。

さらに考えてみると、レンダラーは、レンダリングしようとしているエンティティのインスタンスを照会する必要がある場合があります。車両にマップ上の位置を取得するメソッドがあり、レンダラーがそれらの値を取得してレンダリングする必要があるとします。正しい位置; そのため、Renderer インターフェイスは Renderable のインスタンスを受け取ります。

interface Renderable {
    void render();
}

interface Vehicle extends Renderable {
    void drive();
}

interface Renderer<T extends Renderable> {
    void render(T renderable);
}

public class VehicleRenderer implements Renderer<Vehicle> {
    public void Render(Vehicle renderable) {
        // TODO: Render a Vehicle.
    }
}

public class Car implements Vehicle {
    private Renderer<Vehicle> renderer;

    public void setRenderer(Renderer<Vehicle> renderer) {
        this.renderer = renderer;
    }

    public void render() {
        renderer.render(this);
    }

    public void drive() {
        // TODO: Drive the car.
    }
}
于 2013-01-14T23:38:08.963 に答える
0

メソッドのコードがrender異なるクラス間で同一になる場合は、次の手順を実行します。

AbstractRenderableを実装するという抽象クラスを導入しますRenderable。次にCarBicycle、 などのクラスを拡張AbstractRenderableして実装しますVehicle(またはPlayerなど)。

AbstractRenderableクラスで、メソッドを実装しますrender。そうすれば、すべての車、自転車などは「同一の」レンダリング コードに依存します。Tankさらに、たとえばレンダリング コードが異なる場合は、renderメソッドを単純にオーバーライドできます。

于 2013-01-14T22:34:40.397 に答える