정의
복합체 패턴의 구조는 크게 3가지로 분류된다.
1. Base Component
클라이언트가 Composition(복합체) 내의 오브젝트들을 다루기 위해 제공되는 인터페이스를 말합니다.
베이스 컴포넌트는 인터페이스 또는 추상 클래스로 정의되며 모든 오브젝트들에게 공통되는 메소드를 정의해야 합니다.
2. Leaf
Composition 내의 오브젝트들의 행동을 정의합니다.
단일 객체를 표현할 클래스로, 그룹의 구성원 역할을 하며 트리구조로 따지면 가장 밑단에 존재하는 나뭇잎 역할을 한다고 보면 됩니다.
Base Component를 구현합니다. 그리고 다른 컴포넌트에 대해 참조를 가지면 안됩니다.
3. Composite
Composition(복합체)를 표현할 클래스로, 자식으로 여러개의 Component 타입 멤버를 수용할 수 있도록 구현되어 있어야 합니다.
Leaf 객체들로 이루어져 있으며 Base Component 내 명령들을 구현합니다.
파워포인트에 삼각형, 원을 각각 하나씩 만들어 놓고 삼각형과 원을 그룹화 했다고 가정하겠습니다. 이제 우리는 모든 도형을 빨강색으로 색을 칠하려고 합니다.
이때 우리가 채우기 버튼을 누를 때 선택하는 것이 어떤 도형인지, 혹은 그룹인지에 대해서 구분하지 않아도 됩니다. 파워포인트에서는 도형 하나에 대한 채우기와 그룹 전체에 대한 채우기 버튼이 같습니다.
1. Base Component
Base Component는 Leaf와 Composite의 공통되는 메소드들을 정의해야 합니다.
예제에서는 Shape 인터페이스 내에 각각 도형마다 색을 입히는 draw() 메소드를 정의하도록 하겠습니다.
Shape.java
public interface Shape {
public void draw(String fillColor);
}
2. Leaf Objects
Leaf 객체들은 복합체에 포함되는 요소로, Base Component를 구현해야 합니다.
예제에서는 Triangle과 Circle 클래스를 정의하도록 하겠습니다.
Triangle.java
public class Triangle implements Shape {
@Override
public void draw(String fillColor) {
System.out.println("Drawing Triangle with color " + fillColor);
}
}
Circle.java
public class Circle implements Shape {
@Override
public void draw(String fillColor) {
System.out.println("Drawing Circle with color " + fillColor);
}
}
3. Composite Objects
Composite 객체는 Leaf 객체들을 포함하고 있으며, Base Component를 구현할 뿐만 아니라 Leaf 그룹에 대해 add와 remove를 할 수 있는 메소드들을 클라이언트에게 제공합니다.
Drawing.java
public class Drawing implements Shape {
// Leaf 객체들을 저장할 수 있는 구조체
private List<Shape> shapeList = new ArrayList<Shape>();
@Override
public void draw(String fillColor) {
for(Shape s : shapeList) {
s.draw(fillColor);
}
}
// adding shape to drawing
public void add(Shape s) {
shapeList.add(s);
}
// removing shape from drawing
public void remove(Shape s) {
shapeList.remove(s);
}
// removing all shapes
public void clear() {
System.out.println("Clearing all the shapes from drawing");
this.shapes.clear();
}
}
여기서 중요한 것은 Composite Object 또한 Base Component를 구현해야 한다는 것입니다.
그렇게 해야만 클라이언트가 Composite 객체에 대해서 다른 Leaf들과 동일하게 취급될 수 있습니다.
이제 위에서 작성한 예제 코드를 테스트 할 수 있는 코드를 작성해 보겠습니다.
TestCompositePattern.java
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");
}
}
}
출력 결과
Drawing Triangle with color Red
Drawing Triangle with color Red
Drawing Circle with color Red
Drawing Triangle with color Green
Drawing Triangle with color Green
Drawing Circle with color Green
Drawing Triangle with color Green
Drawing Circle with color Green