1

这个问题是指在此处找到的委托设计模式。

我的游戏引擎有许多接口代表各种实体:

  • 播放器
  • 车辆
  • 等等

并且每一个都可以渲染,因此它们实现了包含方法的 Renderable 接口render()

方法一

使用委托,示例如下所示:

public interface Vehicle {

    public void drive();

}

public class Car implements Vehicle {

    public Renderable renderable;

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

}

每当我想渲染一辆车时,我只需调用car.renderable.render();.

这种方法的问题是我无法创建一个 List 并遍历它。

方法二

为了解决这个问题,我可以让 Vehicle 扩展 Renderable:

public interface Vehicle extends Renderable {

    public void drive();

}

但问题在于,如果我定义 Car、Bicycle、Truck、Tank 等,这些类中的每一个都必须填写 render() 的代码(这可能是相同的)。

有没有办法保持在我的 Vehicle 接口中扩展 Renderable 的好处,而不必在所有实现 Vehicle 的具体类中定义 render() ?

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 的建议。我不确定我在想什么。

于 2013-01-14T22:40:08.337 回答
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方法的代码在不同的类之间是相同的,则执行以下操作:

引入一个名为AbstractRenderableimplements的抽象类Renderable。然后让Car,Bicycle等类扩展AbstractRenderable和实现Vehicle(或Player, 等)。

AbstractRenderable类中,实现render方法。这样,所有汽车、自行车等都依赖于“相同”的渲染代码。另外,如果渲染代码确实不同Tank,例如,您可以简单地覆盖该render方法。

于 2013-01-14T22:34:40.397 回答