2012-09-29 5 views
1

글자 하나의 그래픽 객체가 그룹과 사각형으로 확장 된 컴포지션 패턴이 사용되었습니다. 그룹은 많은 직사각형과 그룹을위한 paint() 메소드 호출을 가질 수 있고, 직사각형의 페인트 메소드를 호출 할 수 있으며, 각 사각형은 그 자체를 그립니다.이 컴포지션의 데코레이터 패턴 사용

이제 어떻게 든 왼쪽 또는 오른쪽에 사각형을 정렬하기 위해 데코레이터 패턴을 사용해야합니다. 이제 그룹에 데코레이터를 사용하면 그룹 좌표를 정렬합니다. 그러나 모든 사각형이 그려지기 때문에 효과가 없습니다.

그래서 여기에 장식 패턴을 어떻게 사용할 수 있습니까?

내가 사용하는 유일한 방법은 모든 사각형 주위의 장식 자 래퍼와 그룹의 모든 요소를 ​​정렬해야한다는 것입니다. 그러나 이것은 데코레이터 패턴의 정책에 어긋나지 않는가? 그룹은 기술적으로 목록에 무엇이 있는지 모릅니다. elemnts는 GraphicObject 인스턴스이고 사각형은 사각형을 그리기 전에 좌표를 수정하는 데코레이터로 둘러싸여 있습니다.) 메소드를 호출합니다.

이것이 유일한 방법 인 경우 어떻게 그 항목을 꾸미는데 사용합니까? 여기에 반성을 사용해야합니까, 아니면 다른 /보다 정확한 방법이 있습니까?

일부 코드 : I 그룹에 추가하기 전에 장식 내부의 사각형을두고있어 어디 다섯 번째 줄에서 잘

if (mainGroup == null) { 
     mainGroup = new Group(); 

     // first line 
     currentBounds = convertToBoundsForLine(x, y, width, lineHeight, 1); 
     //System.out.format("current bounds: x1=%d, y1=%d, x2=%d, y2=%d%n", currentBounds.getX(), currentBounds.getY(), currentBounds.getX2(), currentBounds.getY2()); 
     GraphicObject rect1 = new Rectangle(currentBounds); 
     mainGroup.addChild(rect1); 

     // other lines... 

     // fifth line 
     currentBounds = convertToBoundsForLine(x, y, width, lineHeight, 5); 
     //System.out.format("current bounds: x1=%d, y1=%d, x2=%d, y2=%d%n", currentBounds.getX1(), currentBounds.getY1(), currentBounds.getX2(), currentBounds.getY2()); 
     GraphicObject rect5 = new Rectangle(currentBounds); 

     // this is with the decorator wrapper around - should I use reflection here? 
     GraphicObject blabla = new DecoratorLeft(rect5); 
     mainGroup.addChild(blabla); 

, 당신이 볼 수있는, 그래서 반사를 사용하는 모든 그들을 사용해야합니다 그룹에 추가되는 직사각형. 아니면 더 좋은 방법이 있을까요?

아니면 일반적으로 여기에 데코레이터를 완전히 사용하는 방식입니까? 사전에

감사합니다.

편집 :

가 여기 내 페인트 방법은 그룹의 구현 방법은 :

public void draw(Graphics g, AlignStrategy align) { 
    for (GraphicObject graphic: children) { 
     graphic.draw(g, align); 
    } 
} 

그룹은 단지 아이들이 방법을 그릴 호출합니다.

제 의견에 따르면 데코레이터는 제 의견에 보편적이어야합니다. 당신이 준 의견에 따르면 그것이 종속적 인 것처럼 보입니다. 나는 그룹이 기본적으로 정렬에 의존한다는 것을 의미합니까? 만약 객체를 회전시키는 데코레이터를 만들었거나 좌표 x를 y로 바꾼다면 어떻게 될까요? 왼쪽, 오른쪽 또는 중앙 정렬에 관한 것이 아니라 장식 자에게 코드를 너무 많이 적용하지 않고 작업하는 데 대한 것입니다.

+0

그리기 프로세스가 어떻게 작동하는지 설명해 주시겠습니까? 나는 직사각형의 그룹이 어떻게 만들어 지는지에 대한 아이디어를 가지고 있습니다. 그러나 그림이 어떻게 작동 하는지를 알지 못했을 때, 그림 장식이이 그림에 어떻게 들어 맞는지 나는 알지 못합니다. – user1201210

+0

잘. 그룹 jus는 자신이 가지고있는 모든 사각형에서 페인트를 호출합니다. 각 직사각형에는 자체 좌표가 있으며 페인트 방법에 따라 사각형이 그래픽 G 변수에 그려지며 그래픽 G 변수는 해당 그룹에서 매개 변수로 제공됩니다. 기본적으로 내 데코레이터는 사각형을 래핑합니다. 그룹은 사각형에 대한 좌표가 변하도록 장식자를 호출합니다. 데코레이터는 래핑 된 사각형에 paint 메소드를 호출하고 정렬됩니다. 데코레이터는 직사각형에 이전 좌표를 반환합니다. –

+0

@Dynguss 태그를 추가하는 것을 잊어 버렸습니다. 위의 내 코멘트를 참조하십시오. –

답변

1

당신은 GraphicObject, Group, Rectangle 뒤에 코드를 완벽하게 제어 할 수 있고, 경우 등 (즉, 모든 코드의 경우), 그럼 내가 갈 수있는 하드 방법이 될 수있는 장식 패턴을 사용하여 생각합니다. AWT의 Layout 접근법과 유사한 코드를 사용하여 드로잉 정렬을 구현하는 것이 더 간단합니다. 부모 객체 (예 : Group)에 부모 자식 배열을 관리하는 단일 Layout 객체가 제공됩니다. 기본 레이아웃은 하위 항목에 영향을주지 않습니다. "왼쪽 정렬"및 "오른쪽 정렬"레이아웃은 그림 그리기 전에 어느 정도 시간이 소요되는 레이아웃 단계에서 어린이에게 필요한 위치 변경을 수행합니다.따라서 Group에는 맞춤형 버전으로 필요할 때 대체 할 수있는 기본값 인 Layout 개체가 있습니다.

드로잉 개체 뒤에 코드를 제어 할 수없는 경우 Group 주위의 데코레이터가 모든 자식을 꾸미는 것보다 효과적 일 것이라고 생각합니다. Group -level 데코레이터의 paint() 메소드는 자식 호출시 정렬을 관리합니다. 이렇게하면 드로어 블 오브젝트 당 하나의 데코레이터가 아닌 Group 당 하나의 데코레이터 만 있습니다. 이것은 기본적으로 데코레이터 클래스에 포함 된 레이아웃 코드이지만 레이아웃 코드를 분해하여 데코레이터가 호출하도록 할 수 있습니다.

편집 : 다음은 두 번째 사례의 예입니다. 간단하게 유지하기 위해 세부 정보가 아닌 필요한 부분 만 나열합니다.

public class GroupDecorator extends GraphicObject { //or extends whatever is best 
    public GroupDecorator(Group wrappedGroup) { 
     myGroup = wrappedGroup; 
    } 

    public void paint() { //Assume this is your common paint() method 
     //note I'm making up the names here, since I don't know them 
     List groupsChildren = myGroup.getChildren(); 

     //The type of alignment is stored somewhere in this object 
     //or is hard-coded. That's up to you. I'll assume it's stored somewhere... 

     if (isAlignedLeft()) { 
      //align all the children to the left here 
     } else if (isAlignedRight()){ 
      //align all the children to the right here 
     } else { 
      //do nothing because no alignment is necessary 
     } 

     //call the wrapped Group's paint now. It will call its children's paint()s. 
     myGroup.paint(); 

     //Unalign all the children here, if necessary, to put them back in 
     //their original state. How you implement that is up to you. 
    } 

} 
// Somewhere in your main code... 

    mainGroup = new Group(); 

    //Decorate mainGroup now... 
    GroupDecorator decoratedGroup = new GroupDecorator(mainGroup); 
    //Configure decoratedGroup to align however you want. 

    // first line 
    GraphicObject rect1 = new Rectangle(); 
    mainGroup.addChild(rect1); 

    // other lines... 

    // fifth line 
    GraphicObject rect5 = new Rectangle(); 


    //Now use decoratedGroup now in place of mainGroup. 
+0

이 경우 데코레이터 패턴을 사용하는 것이 좋습니다. 그리고 예, 코드를 완전히 제어 할 수 있습니다. 그룹 주위에 데코레이터를 배치하는 것은 그룹 오브젝트가 정렬되지만 내부의 직사각형은 정렬되지 않는다는 것입니다. 그룹을 수정하면 아마도 데코레이터 패턴의 정책에 어긋날까요? 그룹이 수정 되었기 때문에? 음, 여기에 환상이 부족한지도 모르겠군요. 상상력을 보여 주실 수 있습니까? –

+0

@ArturasM 두 번째 접근법을 설명하는 예제를 추가했습니다. – user1201210

+0

글쎄, 나는 네가 그분의 모범을 정확하게 이해했는지 확신 할 수 없다. 하지만 그래, 고마워, 내가 먼저 내 게시물을 편집했지만 지금은 다시 귀하의 게시물을 읽고 어쩌면 내가 잘못 이해했는지, 아마 그것을 시도해 볼게, 흠. 감사. –

관련 문제