- Composite 패턴 : 그릇과 내용물을 동일시한다
Composite 패턴은 컴퓨터 파일 시스템의 '디렉터리(Directory)'처럼 '중첩'된 구조, 재귀적인 구조를 만들어내는 패턴이다. 그릇과 내용물을 동일하게 만들어내는 것이 특징이다.
- 어떤 경우에 사용할까?
그릇과 내용물을 같은 종류로 취급하면 편리한 경우가 있다. Composite 패턴을 사용하면 그릇 안에 내용물을 넣을 수도 있고, 더 작은 그릇을 넣을 수도 있다. 이러한 형태로 중첩된 구조, 재귀적인 구조를 만들 수 있다.
- 예제 코드
이름 | 설명 |
Entry | File과 Directory를 동일시하는 추상 클래스 |
File | 파일을 나타내는 클래스 |
Directory | 디렉터리를 나타내는 클래스 |
Main | 동작 테스트용 클래스 |
- Entry 클래스
public abstract class Entry {
// 이름을 얻는다
public abstract String getName();
// 크기를 얻는다
public abstract int getSize();
// 목록을 표시한다
public void printList() {
printList("");
}
// prefix를 앞에 붙여서 목록을 표시한다
protected abstract void printList(String prefix);
// 문자열 표시
@Override
public String toString() {
return getName() + " (" + getSize() + ")";
}
}
- File 클래스
public class File extends Entry {
private String name;
private int size;
public File(String name, int size) {
this.name = name;
this.size = size;
}
@Override
public String getName() {
return name;
}
@Override
public int getSize() {
return size;
}
@Override
protected void printList(String prefix) {
System.out.println(prefix + "/" + this);
}
}
- Directory 클래스
import java.util.ArrayList;
import java.util.List;
public class Directory extends Entry {
private String name;
private List<Entry> directory = new ArrayList<>();
public Directory(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public int getSize() {
int size = 0;
for(Entry entry : directory) {
size += entry.getSize();
}
return size;
}
@Override
protected void printList(String prefix) {
System.out.println(prefix + "/" + this);
for(Entry entry : directory) {
entry.printList(prefix + "/" + name);
}
}
// 디렉터리 엔트리를 디렉터리에 추가한다
public Entry add(Entry entry) {
directory.add(entry);
return this;
}
}
- Main 클래스
public class Main {
public static void main(String[] args) {
System.out.println("Making root entries...");
Directory rootdir = new Directory("root");
Directory bindir = new Directory("bin");
Directory tmpdir = new Directory("tmp");
Directory usrdir = new Directory("usr");
rootdir.add(bindir);
rootdir.add(tmpdir);
rootdir.add(usrdir);
bindir.add(new File("vi", 10000));
bindir.add(new File("latex", 20000));
rootdir.printList();
System.out.println();
System.out.println("Making user entries...");
Directory youngjin = new Directory("youngjin");
Directory gildong = new Directory("gildong");
Directory dojun = new Directory("dojun");
usrdir.add(youngjin);
usrdir.add(gildong);
usrdir.add(dojun);
youngjin.add(new File("diary.html", 100));
youngjin.add(new File("Composite.java", 200));
gildong.add(new File("memo.tex", 300));
dojun.add(new File("game.doc", 400));
dojun.add(new File("junk.mail", 500));
rootdir.printList();
}
}
참고문헌 : 유키 히로시 저/김성훈 역(2022), JAVA 언어로 배우는 디자인 패턴 입문, 영진닷컴
참고자료 : https://refactoring.guru/ko/design-patterns/composite