객체들을 트리 구조로 구성하여 부분-전체 계층을 표현하는 패턴, 사용자가 개별 객체와 개별 객체들을 모아서 만들어진 복합 객체를 다룰 때, 모두 동일한 방식으로 다룰 수 있게 하는 패턴
- Component : 전체 클래스의 공통 행위를 정의해놓은 인터페이스
- Leaf : 다른 객체를 포함하지 않는 가장 작은 단위의 Component 인터페이스 구현 클래스
- Composite : Leaf와 Composite로 구성된 Component 인터페이스 구현 클래스
- Client : Composite 인터페이스를 통해 객체 조작
디렉토리에 파일을 추가한다고 가정해보자. 디렉토리에 파일을 직접 저장할 수 있지만 파일이 들어있는 디렉토리를 여러개 합쳐서 저장할 수 있다.
[FileSystem.java]
public interface FileSystem {
String getName();
int getSize();
void info();
}
[File.java]
public class File implements FileSystem{
private String name;
private int size;
public File(String name, int size) {
this.name = name;
this.size = size;
}
@Override
public String getName() {
return this.name;
}
@Override
public int getSize() {
return this.size;
}
@Override
public void info() {
System.out.println("file name : " + this.name + ", file size : " + this.size);
}
}
[Directory.java]
public class Directory implements FileSystem {
private List<FileSystem> child = new ArrayList<>();
private String name;
public Directory(String name) {
this.name = name;
}
public void add(FileSystem fileSystem) {
child.add(fileSystem);
}
@Override
public String getName() {
return this.name;
}
@Override
public int getSize() {
int size = 0;
for (FileSystem file : child) {
size += file.getSize();
}
return size;
}
@Override
public void info() {
System.out.println("dir name : " + this.name);
System.out.println("----------------------------start dir: " + this.name);
for (FileSystem file : child) {
file.info();
}
System.out.println("============================end dir: " + this.name);
System.out.println();
}
}
[Client.java]
public class Client {
public static void main(String[] args) {
File file1 = new File("_3015", 15);
File file2 = new File("_10798", 27);
File file3 = new File("_1089", 53);
Directory dir1 = new Directory("baekjoon");
dir1.add(file1);
dir1.add(file2);
dir1.add(file3);
Directory dir2 = new Directory("designPattern");
File composite = new File("composite", 30);
File proxy = new File("proxy", 40);
File templateMethod = new File("templateMethod", 55);
dir2.add(composite);
dir2.add(proxy);
dir2.add(templateMethod);
Directory rootDir = new Directory("root");
rootDir.add(dir1);
rootDir.add(dir2);
rootDir.add(new File("read.me", 10));
System.out.println("rootDir size : " + rootDir.getSize());
System.out.println("rootDir name : " + rootDir.getName());
rootDir.info();
}
}