객체들을 트리 구조로 구성한 후 개별 객체들처럼 작업할 수 있도록 하는 구조 패턴이다. 객체 트리의 모든 컴포넌트들에 대해 재귀적으로 행동을 실행할 수 있다.
// Component 인터페이스
interface Graphic {
void move(int x, int y);
void draw();
}
// Leaf 클래스
class Dot implements Graphic {
private int x, y;
public Dot(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public void move(int x, int y) {
this.x += x;
this.y += y;
}
@Override
public void draw() {
System.out.println("Drawing a dot at (" + x + ", " + y + ")");
}
}
// Leaf를 확장한 Circle 클래스
class Circle extends Dot {
private int radius;
public Circle(int x, int y, int radius) {
super(x, y);
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing a circle at (" + x + ", " + y + ") with radius " + radius);
}
}
// Composite 클래스
class CompoundGraphic implements Graphic {
private final List<Graphic> children = new ArrayList<>();
public void add(Graphic child) {
children.add(child);
}
public void remove(Graphic child) {
children.remove(child);
}
@Override
public void move(int x, int y) {
for (Graphic child : children) {
child.move(x, y);
}
}
@Override
public void draw() {
System.out.println("Drawing a compound graphic:");
for (Graphic child : children) {
child.draw();
}
}
}
// Client 클래스
class ImageEditor {
private CompoundGraphic all;
public void load() {
all = new CompoundGraphic();
all.add(new Dot(1, 2));
all.add(new Circle(5, 3, 10));
}
public void groupSelected(List<Graphic> components) {
CompoundGraphic group = new CompoundGraphic();
for (Graphic component : components) {
group.add(component);
all.remove(component);
}
all.add(group);
all.draw();
}
public void drawAll() {
all.draw();
}
}
public class Main {
public static void main(String[] args) {
ImageEditor editor = new ImageEditor();
editor.load();
List<Graphic> selectedComponents = new ArrayList<>();
selectedComponents.add(new Dot(10, 20));
selectedComponents.add(new Circle(15, 25, 5));
editor.groupSelected(selectedComponents);
editor.drawAll();
}
}
장점