패턴명칭
Composite
필요한 상황
배열이나 리스트 등과 같은 컨테이너와 컨테이너를 구성하는 구성 요소를 동일하게 처리하기 위한 패턴이다. 컨테이너와 구성 요소는 동일하게 처리되므로 컨테이너 안에는 또 다른 컨테이너를 포함할 수 있다.
예제 코드

우리가 흔히 접하는 폴더와 파일 개념이다. 폴더와 파일을 동일한 개념으로 다루기 위해 Unit이라는 추상 클래스를 두고, 폴더와 파일은 이 Unit을 상속받아 처리한다. Folder 클래스는 다시 여러개의 폴더와 파일을 담을 수 있으므로 Unit을 여러개 담을 수 있도록 한다. 먼저 Unit 클래스는 다음과 같다.
package tstThread;
public abstract class Unit {
private String name;
public Unit(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String toString() {
return name + "(" + getSize() + ")";
}
public abstract int getSize();
}
이 Unit 클래스를 상속받는 File 클래스는 다음과 같다.
package tstThread;
public class File extends Unit {
private int size;
public File(String name, int size) {
super(name);
this.size = size;
}
@Override
public int getSize() {
return size;
}
}
Folder 클래스는 다음과 같다.
package tstThread;
import java.util.Iterator;
import java.util.LinkedList;
public class Folder extends Unit {
private LinkedList<Unit> units = new LinkedList<Unit>();
public Folder(String name) {
super(name);
}
@Override
public int getSize() {
int size = 0;
Iterator<Unit> it = units.iterator();
while(it.hasNext()) {
Unit unit = it.next();
size += unit.getSize();
}
return size;
}
public boolean add(Unit unit) {
units.add(unit);
return true;
}
private void list(String indent, Unit unit) {
if(unit instanceof File) {
System.out.println(indent + unit);
} else {
Folder dir = (Folder)unit;
Iterator<Unit> it = dir.units.iterator();
System.out.println(indent + "+" + unit);
while(it.hasNext()) {
list(indent + " ", it.next());
}
}
}
public void list() {
list("", this);
}
}
이 클래스들을 사용하는 코드는 다음과 같다.
package tstThread;
public class Main {
public static void main(String[] args) {
Folder root = new Folder("root");
root.add(new File("a.txt", 1000));
root.add(new File("b.txt", 2000));
Folder sub1 = new Folder("sub1");
root.add(sub1);
sub1.add(new File("sa.txt", 100));
sub1.add(new File("sb.txt", 4000));
Folder sub2 = new Folder("sub2");
root.add(sub2);
sub2.add(new File("SA.txt", 250));
sub2.add(new File("SB.txt", 340));
root.list();
}
}
위 코드의 실행 결과는 다음과 같다.
+root(7690)
a.txt(1000)
b.txt(2000)
+sub1(4100)
sa.txt(100)
sb.txt(4000)
+sub2(590)
SA.txt(250)
SB.txt(340)
Composite 패턴은 집합과 그 구성요소를 동일하게 처리하기 위해 재귀적인 처리가 필수이다.
이 글은 소프트웨어 설계의 기반이 되는 GoF의 디자인패턴에 대한 강의자료입니다. 완전한 실습을 위해 이 글에서 소개하는 클래스 다이어그램과 예제 코드는 완전하게 실행되도록 제공되지만, 상대적으로 예제 코드와 관련된 설명이 함축적으로 제공되고 있습니다. 이 글에 대해 궁금한 점이 있으면 댓글을 통해 남겨주시기 바랍니다.
