2013-05-24 6 views
4

개체의 개체를 만드는 클래스가 있습니다. 모양은 캔버스에 그려진 모양 (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 연산자를 사용하는 문제를 해결합니다.

Shape와 Formation을 하나의 클래스로 병합해야합니까? Visitor 패턴을 구현해야합니까? (그렇다면이 경우 어떻게 수행 될까요?) 또는 내가 생각하지 못했던 다른 것이 있습니까?

+0

내가 왜 캐스팅을 원하지 않는지 모르겠다. 그 문제를 해결 못해? instanceof가 먼저 올바른 인스턴스 유형인지 확인하기 위해 먼저 테스트합니다. – Vegard

+0

대신 일반 Formation 클래스를 사용하는 것은 어떻습니까? 물론 이것은 각 Formation이 근본적으로 다른 경우에는 작동하지 않을 수 있습니다. – nitegazer2003

+2

다운 캐스팅은 못 생기고 확장하기 어려운 솔루션입니다. 방문자는 너가 너무 많은 모양을 얻지 않으며 unkown 모양을 ie 지원하고 싶지 않는 경우에 이해된다. 추가 플러그인을 제공하는 플러그인. 팝업 메뉴를 만드는 것처럼 클래스에 넣고 싶은 것보다 훨씬 더 많은 유형 특정 논리가 있습니다. 어쩌면 FormationFactoryVisitor 대신 FormationVisitor를 고려할 수도 있습니다. 그러나 다른 방법은 각 모양에 toFormation() 메서드를 사용하는 것입니다. –

답변

1

모두는 사용자의 ShapeFormation의 분리 정도에 따라 다릅니다. 가장 간단한 해결책은 인터페이스에 Formation createFormation() 메소드를 추가하는 것입니다.

그러나 ShapeFormation을 별도로 유지하려는 경우 더 고급 기능을 수행해야합니다. 방문자 패턴을 사용하지 않는 것이 좋습니다. 매우 유연하지 않기 때문입니다. 이것은 이와 같은 공장 사용할 수 있습니다

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이어야한다

대안으로서, FormationBuilder 클래스를 추가하는 것을 고려 초기화 됨. 이것이 요구 사항에 적합한 지 여부는 코드가 어떻게 구성되어 있는지에 달려 있습니다.

+0

가장 깨끗한 솔루션을 찾는 데 신경 쓰지는 않겠지 만 'toFormation()'접근 방식을 사용할 것입니다. 귀하의 모든 노력에 대한 타이 :) – Lopina