组合需要访问封闭类时的建模?

时间:2013-03-28 15:26:02

标签: java oop design-patterns

我对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);
}

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

怎么可以做得更好?

2 个答案:

答案 0 :(得分:1)

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

 public class AStateObject {

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

 }

因此每个drawable都知道它应该绘制的状态对象。这排除了每个Drawable子类使用单个实例,但在这种情况下,Drawables应该很便宜。

答案 1 :(得分:0)

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

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"
}