2015년 10월 25일 일요일

클래스 디자인 패턴 17. Composite Pattern

1. 개념
  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);
        }
    }
}


  4) 예외를 담기위한 클래스 및 테스트 클래스
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


3. 다이어그램
https://en.wikipedia.org/wiki/Composite_pattern

4. 관련패턴
  1) Command 패턴

  2) Visitor 패턴

  3) Decorator 패턴

댓글 없음:

댓글 쓰기