출처 : 책 - java 언어로 배우는 디자인 패턴 입문
11. Composite - 그릇과 내용물을 동일시하기
1. 목적
- 윈도우에서 폴더는 폴더를 넣을수도 있고 파일을 넣을 수도 있다.
- Composite 패턴은 그릇(폴더)와 내용물(파일)을 동일시해서 재귀적인 구조를 만들기 위한 패턴
2. 예제
(1) Entry - File과 Directory 클래스의 부모 추상클래스
public abstract class Entry {
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() + ")";
}
}
(2) File
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
import java.util.Iterator;
import java.util.ArrayList;
public class Directory extends Entry {
private String name; // 디렉터리의 이름
private ArrayList directory = new ArrayList(); // 디렉터리 엔트리의 집합
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);
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) 예외 처리
public class FileTreatmentException extends RuntimeException {
public FileTreatmentException() {
}
public FileTreatmentException(String msg) {
super(msg);
}
}
(5) Main
public class Main {
public static void main(String[] args) {
try {
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 Kim = new Directory("Kim");
Directory Lee = new Directory("Lee");
Directory Park = new Directory("Park");
usrdir.add(Kim);
usrdir.add(Lee);
usrdir.add(Park);
Kim.add(new File("diary.html", 100));
Kim.add(new File("Composite.java", 200));
Lee.add(new File("memo.tex", 300));
Park.add(new File("game.doc", 400));
Park.add(new File("junk.mail", 500));
rootdir.printList();
} catch (FileTreatmentException e) {
e.printStackTrace();
}
}
}
3. Entry 클래스의 add메소드 예외 처리 관련 다른방법
(1) Entry 클래스 add 메소드 구현하고 예외로 처리
> 위의 예제에서 사용한 방법. 어떤 예외가 발생했는지 표시할 수 있습니다.
(2) Entry 클래스 add 메소드 구현 후 아무것도 실행하지 않는다. 하위 클래스에서 오버라이딩한다.
> 예외를 발생시키지 않고 넘어가는 방법입니다.
(3) Entry 클래스에서 add를 추상메소드로 선언한다.
> File 처럼 add가 필요없는 하위 클래스에서도 정의 해줘야하는 불편함이 있다.
(4) Driectory C클래서에만 add 메소드를 만든다.
> Entry 형에 add 할때마다 (Directory) Entry 로 캐스팅 해줘야한다.
'개발 > 디자인 패턴' 카테고리의 다른 글
[Java 언어로 배우는 디자인 패턴 입문] 구조를 돌아다니기 13. Visitor (0) | 2021.01.11 |
---|---|
[Java 언어로 배우는 디자인 패턴 입문] 동일시하기 12. Decorator (0) | 2021.01.11 |
[Java 언어로 배우는 디자인 패턴 입문] 분리해서 생각하기 10. Strategy (0) | 2021.01.10 |
[Java 언어로 배우는 디자인 패턴 입문] 분리해서 생각하기 9. Bridge (0) | 2021.01.10 |
[Java 언어로 배우는 디자인 패턴 입문] 인스턴스 만들기 8. Abstract Factory (0) | 2021.01.09 |
댓글