관련 문서
복합체(컴포지트 패턴)
위키피디아 - 컴포지트 패턴
설명 및 스도코드
- 객체들을 트리 구조들로 구성한 후, 이러한 구조들과 개별 객체들처럼 작업할 수 있도록 하는 구조 패턴
- 사용자가 단일 객체와 복합 객체 모두 동일하게 다루도록 함
복합체 패턴의 구조
- 컴포넌트(Component) 인터페이스
- 트리의 단순 요소들과 복잡한 요소들 모두에 공통적인 작업 설명
- 잎(Leaf)
- 트리의 기본 요소로 하위 구조가 없음
- 대부분의 실제 작업들을 수행함
- 컨테이너(복합체, Composite)
- 하위 요소들(잎 또는 기타 컨테이너)이 있는 요소
- 자녀들의 구상 클래스들을 알지 못하며 컴포넌트 인터페이스를 통해서만 모든 하위 요소들과 함께 작동
- 요청을 전달받으면 컨테이너는 작업을 하위 요소들에 위임하고 중간 결과들을 처리한 다음 최종 결과들을 클라이언트에 반환
- 클라이언트
- 컴포넌트 인터페이스를 통해 모든 요소들과 작동
- 따라서 클라이언트는 트리의 단순 요소들 또는 복잡한 요소들 모두에 대해 같은 방식으로 작업 가능
복합체 패턴의 적용
- 나무와 같은 객체 구조를 구현해야 할 때
- 클라이언트 코드가 단순 요소들과 복합 요소들을 모두 균일하게 처리하도록 하고싶을 때
다른 패턴과의 관계
- 복합체 패턴 트리를 생성할 때 빌더를 사용할 수 있다. 빌더의 생성 단계들은 재귀적으로 작동하도록 프로그래밍할 수 있기 때문
- 책임 연쇄 패턴은 종종 복합체 패턴과 함께 사용된다. 그러면 잎 컴포넌트가 요청을 받으면 해당 요청을 모든 부모 컴포넌트들의 체인을 통해 객체 트리의 뿌리까지 전달할 수 있다
- 반복자들을 사용해 복합체 패턴 트리들을 순회할 수 있다
- 비지터 패턴을 사용해 복합체 패턴 트리 전체를 대상으로 작업을 수행할 수 있다
- RAM을 절약하기 위해 복합체 패턴 트리의 공유된 잎 노드들을 플라이웨이트들로 구현할 수 있다
- 복합체 패턴 및 데코레이터는 둘 다 구조 다이어그램이 유사하다. 둘 다 재귀적인 합성에 의존하여 하나 또는 불특정 다수의 객체들을 정리하기 때문
- 데코레이터는 복합체 패턴과 비슷하지만 자식 컴포넌트가 하나만 있음
- 데코레이터는 래핑된 객체에 추가 책임들을 추가하는 반면 복합체 패턴은 자신의 자식들의 결과를 요약하기만 함
- 데코레이터를 사용하여 복합체 패턴 트리의 특정 객체의 행동을 확장할 수 있음
- 프로토타입 패턴을 적용하여 복잡한 구조들을 처음부터 다시 건축하는 대신 복제할 수 있음
Java를 이용해 구현한 도형 그리기
public interface Shape {
// 공통 메서드
public void draw(String fillColor);
}
public class Triangle implements Shape {
@Override
public void draw(String fillColor) {
System.out.println("Drawing Triangle with color "+fillColor);
}
}
public class Circle implements Shape {
@Override
public void draw(String fillColor) {
System.out.println("Drawing Circle with color "+fillColor);
}
}
public class Drawing implements Shape {
//collection of Shapes
private List<Shape> shapes = new ArrayList<Shape>();
@Override
public void draw(String fillColor) {
for(Shape sh : shapes) {
sh.draw(fillColor);
}
}
//adding shape to drawing
public void add(Shape s) {
this.shapes.add(s);
}
//removing shape from drawing
public void remove(Shape s) {
shapes.remove(s);
}
//removing all the shapes
public void clear() {
System.out.println("Clearing all the shapes from drawing");
this.shapes.clear();
}
}
public class TestCompositePattern {
public static void main(String[] args) {
Shape tri = new Triangle();
Shape tri1 = new Triangle();
Shape cir = new Circle();
Drawing drawing = new Drawing();
drawing.add(tri1);
drawing.add(tri1);
drawing.add(cir);
drawing.draw("Red");
List<Shape> shapes = new ArrayList<>();
shapes.add(drawing);
shapes.add(new Triangle());
shapes.add(new Circle());
for(Shape shape : shapes) {
shape.draw("Green");
}
}
}