2010年3月25日 星期四

Design Pattern : 11 Composit





當我們遇到有容器(container)與內容(content)需要作遞迴處理
例如要對一個目錄下所有的檔案與目錄都作處理
因為目錄(container)與檔案(content)都可以被裝到目錄下
這時候,可以把兩者都當作是"目錄進入點"(entry)來看
這時候容器與內容就都是屬於同一類的東西

這時候針對entry上定義一個"進入點"所需要的功能
而容器與內容都只是entry的子類別,在遞迴程序的操作上
只要使用屬於entry的method即可,而不用管是容器或是內容

參與者
1.Entry(abstract)
實際執行顯示的是printList(String prefix)
這部份在子類別內實作
而留給外部呼叫的只有printList()



public abstract class Entry {
    public abstract String getName();
    public abstract int getSize();
    public void printList(){
        priinList("");
    }
    protected abstract void printList(String prefix);
}

2.File
把Entry內設定的3個abstract method 實作出來


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 this.name;
    }
    public int getSize() { 
        return this.size;
    }
    protected void printList(String prefix) { 
        System.out.println(prefix+"/"+this);
    }
}

3.Directory
在屬於container的class內使用iterator來迴圈執行entry所提供的method


public class Directory extends Entry {
    private String name;
    private Vector directory=new Vector();
    public Directory(String name){
        this.name=name;
    }
    public String getName() {  
        return this.name;
    }
    public int getSize() { 
        int size=0;
        Iterator it=directory.iterator();
        while(it.hasNext()){
            Entry entry=(Entry)it.next();
            size+=entry.getSize();
        }
        return size;
    }
    protected void printList(String prefix) {
        //把自己列印出來,並叫其子node執行entry的列印指令
        System.out.println(prefix+"/"+this);
        Iterator it=directory.iterator();
        while(it.hasNext()){
            Entry entry=(Entry)it.next();
            entry.printList(prefix+"/"+name);
        }
    }
    public Entry add(Entry entry){
        directory.add(entry);
        return this;
    }
}

4.Main 外部程式


Directory root=new Directory("root");
Directory folder1=new Directory("folder1");
File file1=new File("file01",100);
File file2=new File("file02",200);
root.add(folder1);
folder1.add(file1);
folder1.add(file2);
root.printList(); 



沒有留言: