設計模式:組合(Composite)模式


設計模式:組合(Composite)模式

一、前言

  關於Composite模式,其實就是組合模式,又叫部分整體模式,這個模式在我們的生活中也經常使用,比如說如果讀者有使用Java的GUI編寫過程序的,肯定少不了定義一些組件,初始化之后,然后使用容器的add方法,將這些組件有順序的組織成一個界面出來;或者讀者如果編寫過前端的頁面,肯定使用過<div>等標簽定義一些格式,然后格式之間互相組合,通過一種遞歸的方式組織成相應的結構,這種方式其實就是組合,將部分的組件鑲嵌到整體之中;又或者文件和文件夾的組織關系,通過目錄表項作為共同的特質(父類),一個文件夾可以包含多個文件夾和多個文件,一個文件容納在一個文件夾之中。那么憑什么可以這樣做呢,需要滿足以下兩點,首先整體的結構應該是一棵樹,第二,所有的組件應該有一個共同的父類(有共同的本質),這個父類使得組件中的共同的本質可以提取出來(有了共同語言(父類)),進行互融,其實就是父類使用add方法,這樣子類就可以通過抽象的方式通過父類來表達了,可能有點繞口,讓我們看一個例子。

二、代碼

Entry 抽象類:共同特質
 1 package zyr.dp.composite;
 2 
 3 public abstract class Entry {
 4     public abstract String getName();
 5     public abstract int getSize();
 6     public abstract void printList(String prefix);
 7     public  void printList(){
 8         printList("");
 9     }
10     public  Entry add(Entry entry) throws RuntimeException{
11         throw new RuntimeException();
12     }
13     public  String toString(){
14         return getName()+"<"+getSize()+">";
15     }
16 }

  File 類:實現類,葉子結點

 1 package zyr.dp.composite;
 2 
 3 public class File extends Entry {
 4 
 5     private String name;
 6     private int size;
 7     public File(String name,int size){
 8         this.name=name;
 9         this.size=size;
10     }
11     public String getName() {
12         return name;
13     }
14 
15     public int getSize() {
16         return size;
17     }
18 
19     public void printList(String prefix) {
20         System.out.println(prefix+"/"+this);
21     }
22 
23 }
Directory 類:可擴充節點(中間節點)
 1 package zyr.dp.composite;
 2 
 3 import java.util.ArrayList;
 4 import java.util.Iterator;
 5 
 6 public class Directory extends Entry {
 7 
 8     String name;
 9     ArrayList entrys=new ArrayList();
10     public Directory(String name){
11         this.name=name;
12     }
13     public String getName() {
14         return name;
15     }
16 
17     public int getSize() {
18         int size=0;
19         Iterator it=entrys.iterator();
20         while(it.hasNext()){
21             size+=((Entry)it.next()).getSize();
22         }
23         return size;
24     }
25 
26     public Entry add(Entry entry) {
27         entrys.add(entry);
28         return this;
29     }
30     
31     public void printList(String prefix) {
32         System.out.println(prefix+"/"+this);
33         Iterator it=entrys.iterator();
34         Entry entry;
35         while(it.hasNext()){
36             entry=(Entry)it.next();
37             entry.printList(prefix+"/"+name);
38         }
39     }
40 
41 }

  Main類:組合組件

package zyr.dp.composite;

public class Main {

    public static void main(String[] args) {

        Directory root=new Directory("根目錄");
        
        Directory life=new Directory("我的生活");
        File eat=new File("吃火鍋",100);
        File sleep=new File("睡覺",100);
        File study=new File("學習",100);
        life.add(eat);
        life.add(sleep);
        life.add(study);
        
        Directory work=new Directory("我的工作");
        File write=new File("寫博客",200);
        File paper=new File("寫論文",200);
        File homework=new File("寫家庭作業",200);
        work.add(write);
        work.add(paper);
        work.add(homework);
        
        Directory relax=new Directory("我的休閑");
        File music=new File("聽聽音樂",200);
        File walk=new File("出去轉轉",200);
        relax.add(music);
        relax.add(walk);
        
        Directory read=new Directory("我的閱讀");
        File book=new File("學習書籍",200);
        File novel=new File("娛樂小說",200);
        read.add(book);
        read.add(novel);
        
        root.add(life);
        root.add(work);
        root.add(relax);
        root.add(read);

        root.printList("D:");
        System.out.println("=================");
        work.printList("work");
        System.out.println("=================");
        novel.printList("novel");
        

    }

}

 運行結果:

三、總結

  由此可見,我們以前使用的“容器+內容”,其實是通過組合模式實現的,組合模式保證了容器和內容的一致性,容器里面可以套容器,也可以放內容,但是內容已經是葉子結點了,不能繼續擴充,還記得我們在抽象工廠方式中使用的模式之中,為了將零件組裝成產品,我們就使用了組合模式,非常的有意思,通過遞歸來遍歷所有的內容。組合模式在我們的生活中使用的非常普遍,我們一定要使用好這個模式,理解其中的抽象,特別是add()的定義,抽象類和實現類之間的參數傳遞,這點至關重要,當然我們又使用了模板方法和迭代器,希望大家能明白模式之間的聯系以及相互使用的道理。

  程序代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM