4

我有一个类负责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 合并到一个类中,我是否应该尝试实现访问者模式(如果是这样,在这种情况下将如何完成)或者还有其他我没有想到的东西?

4

1 回答 1

1

这完全取决于您希望Shapes 和Formations 的分离程度。正如您所提到的,最简单的解决方案是Formation createFormation()向接口添加一个方法Shape

但是如果你想保持Shapes 和Formations 分开,你将不得不做一些更高级的事情。我建议不要使用访问者模式,因为它非常不灵活。

作为替代方案,请考虑添加一个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初始化。这是否符合您的需求取决于您的代码的结构。

于 2013-05-24T17:18:01.217 回答