1、什麼是Composite模式?html
Composite模式,能夠藉助計算機文件夾的例子去理解,一個文件夾裏面能夠存放文件,也能夠存放子文件夾,這樣子造成一種結構,這個「文件夾」就相似於一個容器,並且仍是一種具備遞歸結構的容器。咱們能夠用Composite模式創造出這樣的結構,使得容器和內容具備一致性。java
2、Composite模式的原理ide
Client:使用Composite模式的相關類;this
Leaf類:表示內容,能夠是計算機系統文件夾裏面的「文件」;spa
Composite類:表示容器,能夠是計算機系統的文件夾,或者子文件夾;3d
Compenent類:這是一個抽象類,使得Leaf和Composite具備一致性的類;code
3、Composite模式示例htm
一、Entry類:表示目錄條目的抽象類,File類和Directory類是它的子類。blog
package com.cjs.composite; 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); public String toString() { return getName() + " (" + getSize() + ")"; } }
目錄條目與一個名字,能夠經過getName方法獲取這個名字,每個條目都有一個大小,這個大小的值由getSize方法獲取,另外還定義了一個add方法,用於添加子文件夾或者其餘類型的文件。繼承
二、File類:表示文件的類,繼承Entry類,並實現父類Entry的抽象方法;
package com.cjs.composite; public class File extends Entry { private String name; private int size; public File(String name, int size) { this.name = name; this.size = size; } @Override public String getName() { return name; } @Override public int getSize() { return size; } @Override protected void printList(String prefix) { System.out.println(prefix+"/"+this); } }
三、Directory類:表示文件夾類,實現了父類Entry的抽象方法。
package com.cjs.composite; import com.cjs.Strategy.Strategy; import java.util.ArrayList; import java.util.Iterator; public class Directory extends Entry { private String name;//文件夾名字
private ArrayList directory = new ArrayList();//文件夾中目錄條目的集合
public Directory(String name) { this.name = name; } @Override public String getName() { return name; } @Override public int getSize() { int size = 0; Iterator it = directory.iterator(); while (it.hasNext()) { Entry entry = (Entry) it.next(); size += entry.getSize(); } return size; } @Override 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); } } //增長目錄條目
public Entry add(Entry entry) { directory.add(entry); return this; } }
由於是文件夾的類,因此定義了一個ArrayList類型的字段directory,用來保存文件夾中的目錄條目,getSize方法則是用遞歸來計算其大小。
四、Main類
package com.cjs.composite; import com.cjs.composite.Directory; 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 userdir = new Directory("usr"); rootdir.add(bindir); rootdir.add(tmpdir); rootdir.add(userdir); bindir.add(new File("vi", 10000)); bindir.add(new File("latex", 20000)); rootdir.printList(); System.out.println(""); System.out.println("Making user entries..."); Directory yuki = new Directory("yuki"); Directory hanako = new Directory("hanako"); Directory tomura = new Directory("tomura"); userdir.add(yuki); userdir.add(hanako); userdir.add(tomura); yuki.add(new File("diary.html", 100)); yuki.add(new File("memo.txt", 300)); hanako.add(new File("composite.java", 200)); tomura.add(new File("game.doc", 400)); tomura.add(new File("junk.mail", 500)); rootdir.printList(); } catch (FileTreatMentException e) { e.printStackTrace(); } } }
預期文件夾層次結構:
輸出結果: