0

我对 a 的以下设计有疑问Canvas,其中某些domain对象应该由不同的表示figures

我需要一个充当域对象的“封闭”类。它保存应该呈现给用户的数据,例如State. 这个状态有一个名字,当然还有一个状态等作为变量。

这个状态应该用一个 直观地表示Rectangle。因此我认为使用Composition Pattern

interface Drawable {
 void draw();
}

class Rectangle implements Drawable {
    @Override
    void draw() {
        //draw the state as a rectangle depending on the state variables, draw the name etc.
    }
}

interface Figure {
    Drawable getDrawable();
}

class State implements Figure {
    boolean state;
    Rectangle rectangle;
    public Drawable getDrawable() { return rectangle; }
}

现在我可能还有其他对象,它们也实现Figure并因此提供了Drawable用于绘制它们的特定对象。

我的问题是:以下将为draw()每个对象执行正确的方法,但是 draw 方法需要它的封闭类的所有信息。

List<Figure> list;
for (Figure obj : list) {
    obj.getDrawable().draw();
}

该方法如何draw()知道State它的封闭对象的例如和名称变量State,因为它应该基于它绘制它?

我唯一想到的是:

interface Drawable {
 void draw(Figure figure);
}

for (Drawable obj : list) {
    obj.getDrawable().draw(obj);
}

但是调用一个对象感觉不对,并且在同一个语句中提供这个对象作为参数!

怎样才能做得更好?

4

2 回答 2

1

当域对象选择用于表示它的 Drawable 实现时,您已经有了一个逻辑位置,您可以在其中提供对 Drawable 的引用:

 public class AStateObject {

      public Drawable getDrawable() {
           return new Rectangle(this);
      }

 }

所以每个drawable都知道它应该绘制的状态对象。这不包括每个 Drawable 子类使用单个实例,但在这种情况下创建 Drawable 应该很便宜。

于 2013-03-28T15:52:58.240 回答
0

您可以在实例化可绘制对象时传递需要绘制的属性。例如,使用抽象类而不是接口:

public abstract class Drawable {

    private final Map<String, Object> attributes;

    public Drawable(final Map<String, Object> attributes) {
        this.attributes = attributes;
    }

    @SuppressWarnings("unchecked")
    public <T> T getAttribute(final String key) {
        return (T) attributes.get(key);
    }

    public abstract void draw();

}

public class Rectangle extends Drawable {

    public Rectangle(final Map<String, Object> attributes) {
        super(attributes);
    }

    @Override
    public void draw() {
        final String name = getAttribute("name");
        System.out.println(name);
    }

}

public interface Figure {

    public Drawable getDrawable();

}

public class State implements Figure {

    private final Rectangle rectangle;

    public State() {
        final Map<String, Object> attributes = new HashMap<String, Object>();
        attributes.put("name", "the rectangle");
        rectangle = new Rectangle(attributes);
    }

    @Override
    public Drawable getDrawable() {
        return rectangle;
    }

}

然后,在调用时:

final List<Figure> figures = new ArrayList<Figure>();
figures.add(new State());
for (final Figure figure : figures) {
    figure.getDrawable().draw(); // prints "the rectangle"
}
于 2013-03-28T15:49:12.787 回答