Chapter 11. Composite : 그릇과 내용물의 동일시

sua·2022년 4월 9일
0
post-thumbnail

1. 예제 프로그램 - 파일과 디렉토리를 그림으로 표현하는 프로그램
<Entry.java>

package ch11.Sample;

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); // prefix를 앞에 붙여서 일람을
														// 표시한다.

	public String toString() { // 문자열 표현
		return getName() + " (" + getSize() + ")";
	}
}

<File.java>

package ch11.Sample;

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);
	}
}

<FileTreatmentException.java>

package ch11.Sample;

public class FileTreatmentException extends RuntimeException {
    public FileTreatmentException() {
    }
    public FileTreatmentException(String msg) {
        super(msg);
    }
}

<Directory.java>

package ch11.Sample;

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;
		// 자신이 가지고 있는 모든 엔트리에 대해서, getSize( )호출하여 더한다.
		Iterator it = directory.iterator();
		while (it.hasNext()) {
			// entry는 Entry 타입으로 선언되어 있고,
			// Entry는 File이나 Directory의 부모 클래스이기 때문에 둘 다 참조할 수 있다.
			Entry entry = (Entry) it.next();
			// entry가 디렉토리인 경우에는, 다시 이 디렉토리의 getSize( )가 재귀적으로 호출된다. 
			size += entry.getSize(); 
			// => 그릇과 내용물이 동일시 된다.
		}
		return size;
	}

	public Entry add(Entry entry) { // 엔트리의 추가
		// 입력인자로 들어온 Entry(File 또는 Directory 객체)를 벡터에 저장한다.
		directory.add(entry);
		return this;
	}

	protected void printList(String prefix) { // 엔트리의 일람
		System.out.println(prefix + "/" + this);
		// 자신이 가지고 있는 모든 엔트리에 대해서, printList( )호출한다.
		Iterator it = directory.iterator();
		while (it.hasNext()) {
			Entry entry = (Entry) it.next();
			entry.printList(prefix + "/" + name);
		}
	}
}

<Main.java>

package ch11.Sample;

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 Kang = new Directory("Kang");
			usrdir.add(Kim);
			usrdir.add(Lee);
			usrdir.add(Kang);
			Kim.add(new File("diary.html", 100));
			Kim.add(new File("Composite.java", 200));
			Lee.add(new File("memo.tex", 300));
			Kang.add(new File("game.doc", 400));
			Kang.add(new File("junk.mail", 500));
			
			rootdir.printList();
		} catch (FileTreatmentException e) {
			e.printStackTrace();
		}
	}
}


2. 연습 문제 - Entry(또는 하위클래스)의 인스턴스로부터 '풀패스'를 얻는 기능을 추가하는 방법
<Entry.java>

package ch11.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();
    }
}

<File.java>

package ch11.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);
    }
}

<Directory.java>

package ch11.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);
        }
    }
}

<FileTreatmentException.java>

package ch11.A2;

public class FileTreatmentException extends RuntimeException {
    public FileTreatmentException() {
    }
    public FileTreatmentException(String msg) {
        super(msg);
    }
}

<Main.java>

package ch11.A2;

public class Main {
    public static void main(String[] args) {
        try {
            Directory rootdir = new Directory("root");

            Directory usrdir = new Directory("usr");
            rootdir.add(usrdir);

            Directory Kim = new Directory("Kim");
            usrdir.add(Kim);

            File file = new File("Composite.java", 100);
            Kim.add(file);
            rootdir.printList();

            System.out.println("");
            System.out.println("file = " + file.getFullName());     
            System.out.println("Kim = " + Kim.getFullName());     
        } catch (FileTreatmentException e) {
            e.printStackTrace();
        }
    }
}

profile
가보자고

0개의 댓글

관련 채용 정보