1) 의미
그릇과 내용물을 동일시하여 재귀적인 구조를 만드는 패턴
2. 소스
1) 추상 클래스이자 디렌토리 엔트리를 표현하는
Entry 클래스를 작성.
package A2;
public abstract class Entry {
protected Entry parent;
public abstract String getName();
public abstract int getSize();
public Entry add(Entry entry) throws FileTreatmentException {
throw new FileTreatmentException();
}
public void printList() {
printList("");
}
protected abstract void printList(String prefix);
public String toString() {
return getName() + " (" + getSize() + ")";
}
public String getFullName() {
StringBuffer fullname = new StringBuffer();
Entry entry = this;
do {
fullname.insert(0, "/" + entry.getName());
entry = entry.parent;
} while (entry != null);
return fullname.toString();
}
}
2) 파일을 표현하는 file 클래스를 작성
package A2;
public class File extends Entry {
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;
}
protected void printList(String prefix) {
System.out.println(prefix + "/" + this);
}
}
3) 마찬가지로 directory 클래스를 작성
package A2;
import java.util.Iterator;
import java.util.Vector;
public class Directory extends Entry {
private String name;
private Vector directory = new Vector();
public Directory(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getSize() {
int size = 0;
Iterator it = directory.iterator();
while (it.hasNext()) {
Entry entry = (Entry)it.next();
size += entry.getSize();
}
return size;
}
public Entry add(Entry entry) {
directory.add(entry);
entry.parent = this;
return this;
}
protected void printList(String prefix) {
System.out.println(prefix + "/" + this);
Iterator it = directory.iterator();
while (it.hasNext()) {
Entry entry = (Entry)it.next();
entry.printList(prefix + "/" + name);
}
}
}
package A2;
import java.util.Iterator;
import java.util.Vector;
public class Directory extends Entry {
private String name;
private Vector directory = new Vector();
public Directory(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getSize() {
int size = 0;
Iterator it = directory.iterator();
while (it.hasNext()) {
Entry entry = (Entry)it.next();
size += entry.getSize();
}
return size;
}
public Entry add(Entry entry) {
directory.add(entry);
entry.parent = this;
return this;
}
protected void printList(String prefix) {
System.out.println(prefix + "/" + this);
Iterator it = directory.iterator();
while (it.hasNext()) {
Entry entry = (Entry)it.next();
entry.printList(prefix + "/" + name);
}
}
}
4) 예외를 담기위한 클래스 및 테스트 클래스
package A2;
public class FileTreatmentException extends RuntimeException {
public FileTreatmentException() {
}
public FileTreatmentException(String msg) {
super(msg);
}
}
package A2;
public class FileTreatmentException extends RuntimeException {
public FileTreatmentException() {
}
public FileTreatmentException(String msg) {
super(msg);
}
}
package A2;
public class Main {
public static void main(String[] args) {
try {
Directory rootdir= new Directory("root");
Directory bindir= new Directory("bin");
rootdir.add(bindir);
Directory tempdir= new Directory("tmp");
bindir.add(tempdir);
File file = new File("Composite.java", 100);
tempdir.add(file);
rootdir.printList();
System.out.println("");
System.out.println("file = " + file.getFullName());
System.out.println("tmp= " + tempdir.getFullName());
} catch (FileTreatmentException e) {
e.printStackTrace();
}
}
}
결과 :
/root (100)
/root/bin (100)
/root/bin/tmp (100)
/root/bin/tmp/Composite.java (100)
file = /root/bin/tmp/Composite.java
tmp= /root/bin/tmp
/root (100)
/root/bin (100)
/root/bin/tmp (100)
/root/bin/tmp/Composite.java (100)
file = /root/bin/tmp/Composite.java
tmp= /root/bin/tmp
3. 다이어그램
https://en.wikipedia.org/wiki/Composite_pattern4. 관련패턴
1) Command 패턴
2) Visitor 패턴
3) Decorator 패턴
댓글 없음:
댓글 쓰기