컴퍼지트패턴은 구조 패턴 중 하나로, 객체들의 관계를 트리 구조로 구성하여 부분-전체 계층을 표현하는 패턴이다. 사용자는 컴퍼지트패턴을 통해 단일 객체와 복합 객체 모두 동일하게 다룰 수 있다.
사진출처: 위키백과
[구조패턴]
구조(Structural)패턴은 작은 클래스들을 상속과 합성을 이용해 더 큰 클래스를 생성하는 방법을 제공하는 패턴
구조패턴을 사용하면 독립적으로 개발한 클래스 라이브러리를 하나로 사용할 수 있는 장점이 있다. 또 여러 인터페이스를 합성하여 서로 다른 인터페이스들의 통일된 추상을 제공한다.
구조패턴의 중요한 포인트는 인터페이스나 구현을 복합하는것이 아닌, 객체를 합성하는 방법을 제공한다는 것이다. => 런타임 단계에서 복합 방법이나 대상을 변경할 수 있다는 점에서 유연성을 갖는다.
컴퍼지트패턴을 적용하기 위해 실생활 예를 활용해보자!
그림판에 삼각형, 사각형, 동그라미를 만들고 삼각형과 사각형을 그룹화했다고 가정하자! 만들어진 도형들을 모두 빨간색으로 색칠하려고 한다.
이때 우리가 채우기 버튼을 누를 때 선택하는 것이 어떤 도형인지, 혹은 그룹인지에 대해 구분하지 않아도 된다. 그림판에는 도형 하나에 대한 채우기 기능과 그룹에 대한 채우기 기능이 같다.
컴퍼지트 패턴은 전체 도형을 하나의 도형으로 관리할 수 있다는 특징을 갖고 있다.
1. Component
Component에서는 Leaf와 Composite의 공통이 되는 메소드를 정의해야한다.
Shape인터페이스 내 각각 도형에 색을 입히는 draw()메소드를 정의해보자
// Shape.java
public interface Shape {
public void draw(String paintColor);
}
2. Leaf
Leaf객체들은 복합체에 포함되는 요소로, Component를 구현해야한다.
// Triangle.java
public class Triangle implements Shape {
public void draw(String paintColor) {
System.out.println("삼각형이 다음 색상으로 색칠되었습니다. : " + paintColor);
}
}
// Square.java
public class Square implements Shape {
public void draw(String paintColor) {
System.out.println("사각형이 다음 색상으로 색칠되었습니다. : " + paintColor);
}
}
// Circle.java
public class Circle implements Shape {
public void draw(String paintColor) {
System.out.println("동그라미가 다음 색상으로 색칠되었습니다. : " + paintColor);
}
}
3. Composite
Composite객체는 Leaf객체를 포함하고 있고, Component를 구현할 뿐만 아니라 Leaf그룹에 대해 add와 remove를 할 수 있는 메소드를 클라이언트에게 제공한다.
// Drawing.java
public class Drawing implements Shape {
private List<Shape> shapes = new ArrayList<>();
@Override
public void draw(String paintColor) {
for(Shape shape : shapes) {
shape.draw(paintColor);
}
}
public void add(Shape s) {
this.shapes.add(s);
]
public void remove(Shape s) {
this.shapes.remove(s);
}
public void clear() {
System.out.println("모든 도형을 제거합니다.");
this.shapes.clear();
}
}
위 코드에서 중요한 것은 Composite의 객체 또한 Component를 구현해야한다는 것이다. 그렇게 해야만 클라이언트가 Composite객체에 대해 다른 Leaf와 동일하게 취급할 수 있기 때문이다.
// CompositePattern.javva
public class CompositePattern {
public static void main(String args[]) {
Shape triangle = new Triangle();
Shape circle = new Circle();
Shape square = new Square();
Drawing drawing = new Drawing();
drawing.add(triangle);
drawing.add(circle);
drawing.add(square);
drawing.draw("빨간색");
List<Shape> shapes = new ArrayList<>();
shapes.add(drawing);
shapes.add(new Triangle());
shapes.add(new Circle());
for(Shape shape : shapes) {
shape.draw("초록색");
}
}
}
위의 코드에서 보았듯이, drawing객체를 통해 Triangle, Circle, Sqaure등 Leaf객체를 그룹으로 묶어서 한번에 동작할 수 있다. 그룹 뿐만 아니라 다른 도형들도 마찬가지로 Shape인터페이스를 구현하고 있기 때문에, 함께 취급되는 것을 확인할 수 있다.
컴퍼지트패턴 학습 시 참고 블로그: https://readystory.tistory.com/131