2013-05-24 2 views
4

У меня есть класс, который отвечает за создание объектов Formation из Shape объектов. Формы - это то, что имя говорит, фигуры, которые рисуются на холсте (TriangleShape, RectangleShape и т. Д.).Проблемы с instanceOf при создании новых объектов из других объектов

Формирование похоже на формы, но я планирую использовать их по-другому.

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.

Должен ли я объединять форму и форму в одном классе, следует ли пытаться реализовать шаблон посетителя (если так, как это будет сделано в этом случае) или есть ли что-то еще, о чем я не думал?

+0

Я не понимаю, почему вы не хотите сбрасывать? не удастся решить эту проблему? просто для проверки экземпляра сначала, чтобы проверить, является ли он правильным типом экземпляра. – Vegard

+0

А как насчет того, что вместо класса Generation ? Конечно, это может не сработать, если каждая формация принципиально отличается. – nitegazer2003

+2

Downcasting - это уродливое и сложное решение. Посетитель имеет смысл, если вы не получите слишком много фигур и не хотите поддерживать нечеткие формы, т.е. дополнительные плагины. Это имеет еще больший смысл, существует гораздо больше логики типа, чем вы хотите поместить в свой класс, как создание всплывающих меню. Возможно, вы даже можете рассмотреть FormationVisitor вместо FormationFactoryVisitor. Однако другой подход заключается в том, чтобы иметь метод toFormation() для каждой формы. –

ответ

1

Все зависит от того, насколько вы хотите, чтобы ваши Shape s и Formation s быть. Самое простое решение - как вы упомянули - добавить метод Formation createFormation() к интерфейсу Shape.

Но если вы пытаетесь сохранить Shape s и 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 должен быть инициализируется. Независимо от того, соответствует ли это вашим потребностям, зависит от того, как структурирован ваш код.

+0

Несмотря на то, что я бы не прочь остановиться в поиске самого чистого решения, я думаю, что я собираюсь использовать подход 'toFormation()'. Ty для всех ваших усилий :) – Lopina

Смежные вопросы