I have a class that is responsible for creating Formation objects from Shape objects. Shapes are just what the name says, shapes that are being drawn on canvas (TriangleShape, RectangleShape and so on).
Formations are similar to shapes, but I plan on using them in a different way.
The RectangleShape, for example, looks like this:
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);
}
}
I keep a list of all drawn shapes declared as List<Shape> = new ArrayList<>();.
My problem comes when I need to dynamically create a formation from a shape. The first approach was to have a class with methods like this:
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
}
The problem is when I retrieve the shape from my list, it is of type Shape and I cannot call any of those methods without down-casting the shape to a proper class, which then pulls the question of using instanceOf operator.
Should I merge the Shape and Formation in one class, should I try to implement a Visitor pattern maybe (if so, how would that be done in this case) or is there something else I didn't think of?