1. 程式人生 > >面向物件:組合(Composite)模式

面向物件:組合(Composite)模式

 以下內容來自http://www.lifevv.com

本文介紹設計模式中的組合(Composite)模式的概念,用法,以及實際應用中怎麼樣使用組合模式進行開發。

Composite模式的概念

Composite模式是構造型的設計模式之一,通過遞迴手段來構造諸如檔案系統之類的樹形的物件結構;Composite模式所代表的資料構造是一群具有統一介面介面的物件集合,並可以通過一個物件來訪問所有的物件(遍歷)。

Composite模式的類圖描述:

[出自:wikimedia.org]

Component
樹形結構的節點抽象
- 為所有的物件定義統一的介面(公共屬性,行為等的定義)
- 提供管理子節點物件的介面方法
- [可選]提供管理父節點物件的介面方法

Leaf


樹形結構的葉節點。Component的實現子類

Composite
樹形結構的枝節點。Component的實現子類

Composite模式的應用場景

Composite模式概念起來比簡單,簡單一點說,可以使用Composite模式來構造一個具有統一介面介面的樹形的物件群,並可通過該介面訪問物件群的每個物件。

Composite模式的應用範例

我們應用Composite模式來實現檔案系統的檔案/目錄結構:
IFile:File與Folder的共通介面介面。相當於Component。
Folder:目錄。目錄下面有子目錄,檔案。相當於Composite。
File:檔案。存在於目錄之中。相當於Leaf。
Client類:測試類或者說使用類。

程式碼:

  1. import  java.util.ArrayList;  
  2. import  java.util.List;  
  3. public class  Client {  
  4.     public static void  main(String[] args) {  
  5.         //構造一個樹形的檔案/目錄結構
  6.         Folder rootFolder = new  Folder( "c://" );  
  7.         Folder compositeFolder = new  Folder( "composite" );  
  8.         rootFolder.addChild(compositeFolder);  
  9.         Folder windowsFolder = new  Folder( "windows" );  
  10.         rootFolder.addChild(windowsFolder);  
  11.         File file = new  File( "TestComposite.java" );  
  12.         compositeFolder.addChild(file);  
  13.         //從rootFolder訪問整個物件群
  14.         printTree(rootFolder);  
  15.     }  
  16.     private static void  printTree(IFile ifile) {  
  17.         ifile.printName();  
  18.         List <IFile> children = ifile.getChildren();  
  19.         for  (IFile file:children) {  
  20.             if  (file  instanceof  File) {  
  21.                 System.out.print("  " );  
  22.                 file.printName();  
  23.             } else if  (file  instanceof  Folder) {  
  24.                 printTree(file);  
  25.             }  
  26.         }  
  27.     }  
  28. }  
  29. interface  IFile {  
  30.     public void  printName();  
  31.     public boolean  addChild(IFile file);  
  32.     public boolean  removeChild(IFile file);  
  33.     public  List<IFile> getChildren();  
  34. }  
  35. class  File  implements  IFile {  
  36.     private  String name;  
  37.     public  File(String name) {  
  38.         this .name = name;  
  39.     }  
  40.     public void  printName() {  
  41.         System.out.println(name);  
  42.     }  
  43.     public boolean  addChild(IFile file) {  
  44.         return false ;  
  45.     }  
  46.     public boolean  removeChild(IFile file) {  
  47.         return false ;  
  48.     }  
  49.     public  List<IFile> getChildren() {  
  50.         return null ;  
  51.     }  
  52. }  
  53. class  Folder  implements  IFile {  
  54.     private  String name;  
  55.     private  List <IFile> childList;  
  56.     public  Folder(String name) {  
  57.         this .name = name;  
  58.         this .childList =  new  ArrayList<IFile>();  
  59.     }  
  60.     public void  printName() {  
  61.         System.out.println(name);  
  62.     }  
  63.     public boolean  addChild(IFile file) {  
  64.         return  childList.add(file);  
  65.     }  
  66.     public boolean  removeChild(IFile file) {  
  67.         return  childList.remove(file);  
  68.     }  
  69.     public  List<IFile> getChildren() {  
  70.         return  childList;  
  71.     }  
  72. }  
import java.util.ArrayList;
import java.util.List;

public class Client {
    public static void main(String[] args) {
        
        //構造一個樹形的檔案/目錄結構
        Folder rootFolder = new Folder("c://");
        Folder compositeFolder = new Folder("composite");
        rootFolder.addChild(compositeFolder);
        Folder windowsFolder = new Folder("windows");
        rootFolder.addChild(windowsFolder);
        File file = new File("TestComposite.java");
        compositeFolder.addChild(file);
        
        //從rootFolder訪問整個物件群
        printTree(rootFolder);
    }
    
    private static void printTree(IFile ifile) {
        ifile.printName();
        List <IFile> children = ifile.getChildren();
        
        for (IFile file:children) {
            if (file instanceof File) {
                System.out.print("  ");
                file.printName();
            } else if (file instanceof Folder) {
                printTree(file);
            }
        }
    }

}


interface IFile {
    public void printName();
    
    public boolean addChild(IFile file);
    public boolean removeChild(IFile file);
    public List<IFile> getChildren();
}

class File implements IFile {
    private String name;
    
    public File(String name) {
        this.name = name;
    }
    public void printName() {
        System.out.println(name);
    }

    public boolean addChild(IFile file) {
        return false;
    }

    public boolean removeChild(IFile file) {
        return false;
    }

    public List<IFile> getChildren() {
        return null;
    }
    
}

class Folder implements IFile {
    private String name;
    private List <IFile> childList;
    
    public Folder(String name) {
        this.name = name;
        this.childList = new ArrayList<IFile>();
    }
    public void printName() {
        System.out.println(name);
    }

    public boolean addChild(IFile file) {
        return childList.add(file);
    }

    public boolean removeChild(IFile file) {
        return childList.remove(file);
    }

    public List<IFile> getChildren() {
        return childList;
    }
}



執行Client,輸出結果:
C:/Composite>javac *.java
C:/Composite>java Client
c:/
composite
  TestComposite.java
windows
C:/Composite>