樹形結構的處理——組合模式(三)

Liuwei-Sunny發表於2012-09-07

11.3  完整解決方案

      為了讓系統具有更好的靈活性和可擴充套件性,客戶端可以一致地對待檔案和資料夾,Sunny公司開發人員使用組合模式來進行防毒軟體的框架設計,其基本結構如圖11-5所示:

11-5  防毒軟體框架設計結構圖

    在圖11-5中, AbstractFile充當抽象構件類,Folder充當容器構件類,ImageFileTextFileVideoFile充當葉子構件類。完整程式碼如下所示:

import java.util.*;

//抽象檔案類:抽象構件
abstract class AbstractFile {
	public abstract void add(AbstractFile file);
	public abstract void remove(AbstractFile file);
	public abstract AbstractFile getChild(int i);
	public abstract void killVirus();
}

//影象檔案類:葉子構件
class ImageFile extends AbstractFile {
	private String name;
	
	public ImageFile(String name) {
		this.name = name;
	}
	
	public void add(AbstractFile file) {
	   System.out.println("對不起,不支援該方法!");
	}
	
	public void remove(AbstractFile file) {
		System.out.println("對不起,不支援該方法!");
	}
	
	public AbstractFile getChild(int i) {
		System.out.println("對不起,不支援該方法!");
		return null;
	}
	
	public void killVirus() {
		//模擬防毒
		System.out.println("----對影象檔案'" + name + "'進行防毒");
	}
}

//文字檔案類:葉子構件
class TextFile extends AbstractFile {
	private String name;
	
	public TextFile(String name) {
		this.name = name;
	}
	
	public void add(AbstractFile file) {
	   System.out.println("對不起,不支援該方法!");
	}
	
	public void remove(AbstractFile file) {
		System.out.println("對不起,不支援該方法!");
	}
	
	public AbstractFile getChild(int i) {
		System.out.println("對不起,不支援該方法!");
		return null;
	}
	
	public void killVirus() {
		//模擬防毒
		System.out.println("----對文字檔案'" + name + "'進行防毒");
	}
}

//視訊檔案類:葉子構件
class VideoFile extends AbstractFile {
	private String name;
	
	public VideoFile(String name) {
		this.name = name;
	}
	
	public void add(AbstractFile file) {
	   System.out.println("對不起,不支援該方法!");
	}
	
	public void remove(AbstractFile file) {
		System.out.println("對不起,不支援該方法!");
	}
	
	public AbstractFile getChild(int i) {
		System.out.println("對不起,不支援該方法!");
		return null;
	}
	
	public void killVirus() {
		//模擬防毒
		System.out.println("----對視訊檔案'" + name + "'進行防毒");
	}
}

//資料夾類:容器構件
class Folder extends AbstractFile {
	//定義集合fileList,用於儲存AbstractFile型別的成員
	private ArrayList<AbstractFile> fileList=new ArrayList<AbstractFile>();
	private String name;
		
	public Folder(String name) {
		this.name = name;
	}
	
	public void add(AbstractFile file) {
	   fileList.add(file);	
	}
	
	public void remove(AbstractFile file) {
		fileList.remove(file);
	}
	
	public AbstractFile getChild(int i) {
		return (AbstractFile)fileList.get(i);
	}
	
	public void killVirus() {
		System.out.println("****對資料夾'" + name + "'進行防毒");  //模擬防毒
		
		//遞迴呼叫成員構件的killVirus()方法
		for(Object obj : fileList) {
			((AbstractFile)obj).killVirus();
		}
	}
}

      編寫如下客戶端測試程式碼:

class Client {
	public static void main(String args[]) {
        //針對抽象構件程式設計
		AbstractFile file1,file2,file3,file4,file5,folder1,folder2,folder3,folder4;
		
		folder1 = new Folder("Sunny的資料");
		folder2 = new Folder("影象檔案");
		folder3 = new Folder("文字檔案");
		folder4 = new Folder("視訊檔案");
		
		file1 = new ImageFile("小龍女.jpg");
		file2 = new ImageFile("張無忌.gif");
		file3 = new TextFile("九陰真經.txt");
		file4 = new TextFile("葵花寶典.doc");
		file5 = new VideoFile("笑傲江湖.rmvb");

		folder2.add(file1);
		folder2.add(file2);
		folder3.add(file3);
		folder3.add(file4);
		folder4.add(file5);
		folder1.add(folder2);
		folder1.add(folder3);
		folder1.add(folder4);
		
        //從“Sunny的資料”節點開始進行防毒操作
		folder1.killVirus();
	}
}

      編譯並執行程式,輸出結果如下:

****對資料夾'Sunny的資料'進行防毒

****對資料夾'影象檔案'進行防毒

----對影象檔案'小龍女.jpg'進行防毒

----對影象檔案'張無忌.gif'進行防毒

****對資料夾'文字檔案'進行防毒

----對文字檔案'九陰真經.txt'進行防毒

----對文字檔案'葵花寶典.doc'進行防毒

****對資料夾'視訊檔案'進行防毒

----對視訊檔案'笑傲江湖.rmvb'進行防毒

      由於在本例項中使用了組合模式,在抽象構件類中宣告瞭所有方法,包括用於管理和訪問子構件的方法,如add()方法和remove()方法等,因此在ImageFile等葉子構件類中實現這些方法時必須進行相應的異常處理或錯誤提示。在容器構件類FolderkillVirus()方法中將遞迴呼叫其成員物件的killVirus()方法,從而實現對整個樹形結構的遍歷。

      如果需要更換操作節點,例如只需對資料夾“文字檔案”進行防毒,客戶端程式碼只需修改一行即可,將程式碼:

folder1.killVirus();

       改為:

folder3.killVirus();

       輸出結果如下:

****對資料夾'文字檔案'進行防毒

----對文字檔案'九陰真經.txt'進行防毒

----對文字檔案'葵花寶典.doc'進行防毒

       在具體實現時,我們可以建立圖形化介面讓使用者選擇所需操作的根節點,無須修改原始碼,符合“開閉原則”,客戶端無須關心節點的層次結構,可以對所選節點進行統一處理,提高系統的靈活性。

【作者:劉偉  http://blog.csdn.net/lovelion

相關文章