我对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);
}
但是调用一个对象并不合适,并且在同一个语句中提供这个对象作为参数!
怎么可以做得更好?
答案 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"
}