컴포짓 패턴 (Composite)
컴포짓 패턴(Composite Pattern)은 객체들을 트리(Tree) 구조로 구성하여 개별 객체(단일 객체)와 복합 객체(그룹)를 클라이언트 입장에서 똑같은 방법으로 다룰 수 있게 해주는 패턴입니다.
가장 완벽한 예시는 파일 시스템입니다. 폴더 안에는 파일이 있을 수도 있고, 또 다른 폴더가 있을 수도 있습니다. 사용자가 폴더의 getSize()를 호출하면 폴더 안의 모든 파일과 하위 폴더의 크기를 재귀적으로 합산합니다. 파일이든 폴더든 똑같은 인터페이스(컴포넌트)로 취급하기 때문에 처리가 매우 단순해집니다.
<!-- ==========================================
// 📂 FileSystemComponent (공통 인터페이스)
// ==========================================
import java.util.ArrayList;
import java.util.List;
// 단일 객체(File)와 복합 객체(Folder)가 함께 구현할 공통 인터페이스
interface FileSystemComponent {
String getName();
int getSize();
void print(String indent);
}
// ==========================================
// 📂 Leaf (가장 말단 노드 - 파일)
// ==========================================
class File implements FileSystemComponent {
private String name;
private int size;
public File(String name, int size) { this.name = name; this.size = size; }
public String getName() { return name; }
public int getSize() { return size; } // 파일은 자기 자신의 크기 반환
public void print(String indent) {
System.out.println(indent + "📄 " + name + " (" + size + "KB)");
}
}
// ==========================================
// 📂 Composite (자식을 가지는 그룹 노드 - 폴더)
// ==========================================
class Folder implements FileSystemComponent {
private String name;
// 인터페이스(Component)의 리스트를 가지는 것이 핵심! (폴더든 파일이든 다 들어올 수 있음)
private List<FileSystemComponent> children = new ArrayList<>();
public Folder(String name) { this.name = name; }
public void add(FileSystemComponent component) { children.add(component); }
public String getName() { return name; }
// 폴더의 크기는 재귀적으로 모든 자식들의 크기를 합산합니다.
public int getSize() {
int totalSize = 0;
for (FileSystemComponent child : children) {
totalSize += child.getSize(); // 파일이면 자기 크기, 폴더면 재귀 호출됨!
}
return totalSize;
}
public void print(String indent) {
System.out.println(indent + "📁 " + name + " (총 " + getSize() + "KB)");
for (FileSystemComponent child : children) {
child.print(indent + " ");
}
}
}
// ==========================================
// 📂 Main.java (사용 예시)
// ==========================================
public class Main {
public static void main(String[] args) {
Folder root = new Folder("C:");
Folder dev = new Folder("Dev");
Folder docs = new Folder("Docs");
File resume = new File("이력서.pdf", 1024);
File code = new File("Main.java", 15);
File db = new File("oracle.sql", 5000);
docs.add(resume);
dev.add(code);
dev.add(db);
root.add(docs);
root.add(dev);
// root 폴더를 출력하라고 하면, 하위 폴더와 파일의 처리가 연쇄적으로(재귀적으로) 일어납니다.
root.print("");
}
}