Java 組合模式及其應用
導讀 | 組合模式,就是在一個物件中包含其他物件,這些被包含的物件可能是終點物件(不再包含別的物件),也有可能是非終點物件(其內部還包含其他物件,或叫組物件),我們將物件稱為節點,即一個根節點包含許多子節點,這些子節點有的不再包含子節點,而有的仍然包含子節點,以此類推。 |
很明顯,這是樹形結構,終結點叫葉子節點,非終節點(組節點)叫樹枝節點,第一個節點叫根節點。同時也類似於檔案目錄的結構形式:檔案可稱之為終節點,目錄可稱之為非終節點(組節點)。
我們首先來看一個目錄結構的普通實現:
目錄節點:Noder
import java.util.ArrayList; import java.util.List; /** * 目錄節點 * 包含: * 1、目錄名 * 2、下級檔案列表 * 3、下級目錄列表 * 4、新增檔案方法 * 5、新增目錄方法 * 6、顯示下級內容方法 */ public class Noder { String nodeName;//目錄名 //透過構造器為目錄命名 public Noder(String nodeName){ this.nodeName = nodeName; } ListnodeList = new ArrayList();//目錄的下級目錄列表 ListfileList = new ArrayList();//目錄的下級檔案列表 //新增下級目錄 public void addNoder(Noder noder){ nodeList.add(noder); } //新增檔案 public void addFiler(Filer filer){ fileList.add(filer); } //顯示下級目錄及檔案 public void display(){ for(Noder noder:nodeList){ System.out.println(noder.nodeName); noder.display();//遞迴顯示目錄列表 } for(Filer filer:fileList){ filer.display(); } } }
檔案節點:Filer
/** * 檔案節點 * 檔案節點是終節點,無下級節點 * 包含: * 1、檔名 * 2、檔案顯示方法 */ public class Filer { String fileName;//檔名 public Filer(String fileName){ this.fileName = fileName; } //檔案顯示方法 public void display(){ System.out.println(fileName); } }
測試類:Clienter
import java.io.File; public class Clienter { public static void createTree(Noder node){ File file = new File(node.nodeName); File[] f = file.listFiles(); for(File fi : f){ if(fi.isFile()){ Filer filer = new Filer(fi.getAbsolutePath()); node.addFiler(filer); } if(fi.isDirectory()){ Noder noder = new Noder(fi.getAbsolutePath()); node.addNoder(noder); createTree(noder);//使用遞迴生成樹結構 } } } public static void main(String[] args) { Noder noder = new Noder("E://ceshi"); createTree(noder);//建立目錄樹形結構 noder.display();//顯示目錄及檔案 } }
執行結果:
E:\ceshi\目錄1 E:\ceshi\目錄1\目錄3 E:\ceshi\目錄1\檔案2.txt E:\ceshi\目錄2 E:\ceshi\目錄2\檔案3.txt E:\ceshi\檔案1.txt
從上面的程式碼中可以看出,我們分別定義了檔案節點物件與目錄節點物件,這是因為檔案與目錄之間的操作不同,檔案沒有下級節點,而目錄可以有下級節點,但是我們能不能這麼想:既然檔案與目錄都是可以作為一個節點的下級節點而存在,那麼我們可不可以將二者抽象為一類物件,雖然二者的操作不同,但是我們可以在實現類的方法實現中具體定義,比如檔案沒有新增下級節點的方法,我們就可以在檔案的這個方法中丟擲一個異常,不做具體實現,而在目錄中則具體實現新增操作。顯示操作二者都有,可以各自實現。而且由於我們將檔案與目錄抽象為一個型別,那麼結合多型我們可以進行如下實現:
抽象類:Node
/** * 將檔案與目錄統一看作是一類節點,做一個抽象類來定義這種節點,然後以其實現類來區分檔案與目錄,在實現類中分別定義各自的具體實現內容 */ public abstract class Node { protected String name;//名稱 //構造器賦名 public Node(String name){ this.name = name; } //新增節點:檔案節點無此方法,目錄節點重寫此方法 public void addNode(Node node) throws Exception{ throw new Exception("Invalid exception"); } //顯示節點:檔案與目錄均實現此方法 abstract void display(); }
檔案實現類:Filter
/** * 實現檔案節點 */ public class Filer extends Node { //透過構造器為檔案節點命名 public Filer(String name) { super(name); } //顯示檔案節點 @Override public void display() { System.out.println(name); } }
目錄實現類:Noder
import java.util.*; /** * 實現目錄節點 */ public class Noder extends Node { ListnodeList = new ArrayList();//內部節點列表(包括檔案和下級目錄) //透過構造器為當前目錄節點賦名 public Noder(String name) { super(name); } //新增節點 public void addNode(Node node) throws Exception{ nodeList.add(node); } //遞迴迴圈顯示下級節點 @Override void display() { System.out.println(name); for(Node node:nodeList){ node.display(); } } }
測試類:Clienter
import java.io.File; public class Clienter { public static void createTree(Node node) throws Exception{ File file = new File(node.name); File[] f = file.listFiles(); for(File fi : f){ if(fi.isFile()){ Filer filer = new Filer(fi.getAbsolutePath()); node.addNode(filer); } if(fi.isDirectory()){ Noder noder = new Noder(fi.getAbsolutePath()); node.addNode(noder); createTree(noder);//使用遞迴生成樹結構 } } } public static void main(String[] args) { Node noder = new Noder("E://ceshi"); try { createTree(noder); } catch (Exception e) { e.printStackTrace(); } noder.display(); } }
執行輸出結果:
E://ceshi E:\ceshi\檔案1.txt E:\ceshi\目錄1 E:\ceshi\目錄1\檔案2.txt E:\ceshi\目錄1\目錄3 E:\ceshi\目錄2 E:\ceshi\目錄2\檔案3.txt
從上述實現中可以看出:所謂組合模式,其實說的是物件包含物件的問題,透過組合的方式(在物件內部引用物件)來進行佈局,我認為這種組合是區別於繼承的,而另一層含義是指樹形結構子節點的抽象(將葉子節點與數枝節點抽象為子節點),區別於普通的分別定義葉子節點與數枝節點的方式。
這種組合模式正是應樹形結構而生,所以組合模式的使用場景就是出現樹形結構的地方。比如:檔案目錄顯示,多及目錄呈現等樹形結構資料的操作。
原文來自:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2775181/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 設計模式 | 組合模式及典型應用設計模式
- 設計模式學習筆記(十三)組合模式及其在樹形結構中的應用設計模式筆記
- Java設計模式之(十)——組合模式Java設計模式
- 細說 Java 泛型及其應用Java泛型
- java23種設計模式——八、組合模式Java設計模式
- 設計模式學習筆記(十六)迭代器模式及其在Java 容器中的應用設計模式筆記Java
- 深入理解 JavaScript 單例模式及其應用JavaScript單例模式
- 組合模式模式
- 設計模式之--策略模式及其在JDK中的應用設計模式JDK
- 設計模式 - 命令模式詳解及其在JdbcTemplate中的應用設計模式JDBC
- 設計模式學習筆記(十二)享元模式及其應用設計模式筆記
- 設計模式學習筆記(九)橋接模式及其應用設計模式筆記橋接
- 設計模式《組合模式》設計模式
- 【設計模式】組合模式設計模式
- 設計模式-組合模式設計模式
- 組合模式(Composite)模式
- Java 註解及其在 Android 中的應用JavaAndroid
- 設計模式 - 迭代器模式詳解及其在ArrayList中的應用設計模式
- 設計模式學習筆記(十)裝飾器模式及其應用設計模式筆記
- Ajax及其應用
- js設計模式–組合模式JS設計模式
- js設計模式--組合模式JS設計模式
- 設計模式系列 – 組合模式設計模式
- CAS原子操作以及其在Java中的應用Java
- 設計模式學習筆記(十七)中介者模式及其應用場景設計模式筆記
- composite pattern(組合模式)模式
- Java進階篇設計模式之六 ----- 組合模式和過濾器模式Java設計模式過濾器
- 設計模式及其在spring中的應用(含程式碼)設計模式Spring
- 閉包及其應用
- 設計模式學習筆記(八)介面卡模式介紹及其應用設計模式筆記
- PHP 設計模式之組合模式PHP設計模式
- 《Head First 設計模式》:組合模式設計模式
- 設計模式系列之「組合模式」設計模式
- 軟體設計模式————(組合模式)設計模式
- GoLang設計模式20 - 組合模式Golang設計模式
- 極簡設計模式-組合模式設計模式
- 設計模式【11】-- 搞定組合模式設計模式
- 徒手擼設計模式-組合模式設計模式