我有一个类负责从Formation
个对象创建Shape
个对象。形状正如名称所示,在画布上绘制的形状(TriangleShape
,RectangleShape
等等。)
形式类似于形状,但我打算以不同的方式使用它们。
例如,RectangleShape
看起来像这样:
public class RectangleShape extends Shape {
public RectangleShape() {
this(0, 0, 0, 0);
}
public RectangleShape(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.nPoints = 4;
}
@Override
public void drawShape(Graphics2D g) {
Color color = g.getColor();
fillShape(g, new Color(g.getColor().getRed(), g.getColor().getGreen(), g.getColor().getBlue(), 16));
g.setColor(color);
g.drawLine(x, y, x + width, y);
g.drawLine(x, y, x, y + height);
g.drawLine(x, y + height, x + width, y + height);
g.drawLine(x + width, y, x + width, y + height);
}
@Override
public String toString() {
return "Rectangle";
}
@Override
public Shape createCopy() {
return new RectangleShape();
}
@Override
public void fillShape(Graphics2D g) {
xPoints = new int[] {
x,
x,
x + width,
x + width
};
yPoints = new int[] {
y,
y + height,
y + height,
y
};
g.fillPolygon(xPoints, yPoints, nPoints);
}
}
我保留一份声明为List<Shape> = new ArrayList<>();
的所有绘制形状的列表。
当我需要从形状动态创建阵型时,我的问题就出现了。 第一种方法是使用这样的方法:
public static TriangleFormation createFormationFrom(TriangleShape shape) {
// my code here
}
public static RectangleFormation createFormationFrom(RectangleShape shape) {
// my code here
}
public static PentagonFormation createFormationFrom(PentagonShape shape) {
// my code here
}
public static HexagonFormation createFormationFrom(HexagonShape shape) {
// my code here
}
public static OvalFormation createFormationFrom(OvalShape shape) {
// my code here
}
问题是,当我从列表中检索形状时,它的类型为Shape
,如果不将形状转换为适当的类,我就不能调用任何这些方法,这就引出了使用问题instanceOf
运营商。
我是否应该在一个类中合并Shape和Formation,我是否应该尝试实现一个Visitor模式(如果是这样,在这种情况下会怎样做)或者还有其他我没想过的东西?
答案 0 :(得分:1)
这完全取决于您希望Shape
和Formation
分开的程度。最简单的解决方案是 - 如您所述 - 将Formation createFormation()
方法添加到Shape
接口。
但如果你想让Shape
和Formation
分开,你就必须做更先进的事情。我建议不要使用访问者模式,因为它非常不灵活。
作为替代方案,请考虑添加FormationBuilder
类:
public interface FormationBuilder
{
/**
* Builds a particular Formation implementation from the given shape.
* Perhaps the shape is passed into the constructor of the Formation,
* perhaps this method extracts the necessary information to build the
* Formation...
*/
Formation build(Shape shape);
}
这可以用于这样的工厂:
public class FormationFactory
{
private final Map<Class<? extends Shape>, FormationBuilder> builders
= new HashMap<Class<? extends Shape>, FormationBuilder>();
public <T extends Shape> void register(
Class<T> shapeType, FormationBuilder builder);
{
builders.put(shapeType, builder);
}
public Formation getFormation(Shape shape)
{
return builders.get(shape.getClass()).build(shape);
}
}
但现在的问题是,Factory
应该在哪里初始化。这是否符合您的需求取决于您的代码的结构。