1. 程式人生 > >* 24種設計模式——組合模式

* 24種設計模式——組合模式

將物件組合成樹形結構,以表示“部分-整體”的層次結構,使得使用者對單個物件和組合物件的使用具有一致性。

一、公司組織架構1(介面篇)


1. 公司人員介面

public interface ICorp {
	//獲取自己的資訊(每個員工都有資訊,你想隱藏,門兒都沒有)
	public String getInfo();
}
2. 樹葉介面
public interface ILeaf extends ICorp{
	
}
3. 樹枝介面(包括大老闆節點 和 經理節點 )
public interface IBranch extends ICorp{
	//能夠增加小兵(樹葉節點)或者是經理(樹枝節點)—— 不管傳什麼都是向上造型
	public void addSubordinate(ICorp corp);
	//我還要能夠獲得下屬的資訊
	public ArrayList<ICorp> getSubordinate();
}
4. 樹葉實現類
public class Leaf implements ILeaf{
	//葉子叫什麼名字
	private String name = "";
	//葉子的職位
	private String position = "";
	//葉子的薪水
	private int salary = 0;
	//通過建構函式傳遞資訊
	public Leaf(String name, String position, int salary) {
		this.name = name;
		this.position = position;
		this.salary = salary;
	}
	//最小的小兵只能獲得自己的資訊了
	public String getInfo() {
		String info = "";
		info = "名稱:"+this.name;
		info = info + "\t職位:"+this.position;
		info = info + "\t薪水:"+this.salary;
		return info;
	}
}
5. 樹枝實現類
public class Branch implements IBranch{
	//儲存子節點的資訊
	private ArrayList subordinateList = new ArrayList();
	//樹枝節點的名稱
	private String name = "";
	//樹枝節點的職位
	private String position = "";
	//樹枝節點的薪水
	private int salary = 0;
	//通過建構函式傳遞樹枝節點的引數
	public Branch(String name, String position,int salary) {
		this.name = name;
		this.position = position;
		this.salary = salary;
	}
	//增加一個下屬,可能 是小頭目,也可能是個小兵
	public void addSubordinate(ICorp corp) {
		this.subordinateList.add(corp);
	}
	//我有哪些下屬
	public ArrayList<ICorp> getSubordinate() {
		return this.subordinateList;
	}
	//得到自己的資訊
	public String getInfo() {
		String info = "";
		info = "名稱:"+this.name;
		info = info + "\t職位:"+this.position;
		info = info + "\t薪水:"+this.salary;
		return info;
	}
}
6. 場景類
public class Client {
	public static void main(String[] args) {
		//首先是組裝一個組織結構出來 
		Branch ceo = compositeCorpTree();
		//首先把ceo的資訊打印出來
		System.out.println(ceo.getInfo());
		//然後是所有員工資訊
		System.out.println(getTreeInfo(ceo));
	}
	
	public static Branch compositeCorpTree(){
		//首先產生總經理CEO
		Branch root = new Branch("王大麻子", "總經理", 100000);
		//把三個部門經理產生出來 
		Branch developDep = new Branch("劉大瘸子", "研發部門經理", 10000);
		Branch salesDep = new Branch("馬二柺子", "銷售部門經理", 20000);
		Branch financeDep = new Branch("趙三駝子", "財務部門經理", 30000);
		//再把三個小組長產生出來 
		Branch firstDevGroup = new Branch("楊三也斜","開發一組組長",5000);
		Branch secondDevGroup = new Branch("吳大植株","開發二組組長",6000);
		//把所有的小兵都產生出來 
		Leaf a = new Leaf("a","開發人員",2000);
		Leaf b = new Leaf("b","開發人員",2000);
		Leaf c = new Leaf("c","開發人員",2000);
		Leaf d = new Leaf("d","開發人員",2000);
		Leaf e = new Leaf("e","開發人員",2000);
		Leaf f = new Leaf("f","開發人員",2000);
		Leaf g = new Leaf("g","開發人員",2000);
		Leaf h = new Leaf("h", "銷售人員", 5000);
		Leaf i = new Leaf("i", "銷售人員", 4000);
		Leaf j = new Leaf("j", "財務人員", 5000);
		Leaf k = new Leaf("k", "CEO祕書", 8000);
		Leaf zhengLaoLiu = new Leaf("鄭老六", "研發部副經理", 20000);
		//開始組裝
		//CEO下有三個部門經理和一個祕書
		root.addSubordinate(developDep);
		root.addSubordinate(salesDep);
		root.addSubordinate(financeDep);
		root.addSubordinate(k);
		//研發部經理
		developDep.addSubordinate(firstDevGroup);
		developDep.addSubordinate(secondDevGroup);
		developDep.addSubordinate(zhengLaoLiu);
		//看看兩個開發小組下有什麼
		firstDevGroup.addSubordinate(a);
		firstDevGroup.addSubordinate(b);
		firstDevGroup.addSubordinate(c);
		secondDevGroup.addSubordinate(d);
		secondDevGroup.addSubordinate(e);
		secondDevGroup.addSubordinate(f);
		//再看銷售部下的人員情況
		salesDep.addSubordinate(h);
		salesDep.addSubordinate(i);
		//最後一個財務
		financeDep.addSubordinate(j);
		return root;
	}
	//遍歷整棵樹,只要給我根節點,我就能遍歷出所有的節點
	public static String getTreeInfo(Branch root){
		List<ICorp> subordinateList = root.getSubordinate();
		String info = "";
		for(ICorp s : subordinateList){
			if(s instanceof Leaf){
				info = info + s.getInfo() + "\n";
			}else{	//是個小頭目
				info = info + s.getInfo() + "\n" + getTreeInfo((Branch)s);
			}
		}
		return info;
	}
}
二、公司組織架構(抽象類篇)


主要是把ICorp介面修改為Corp抽象類,抽象出來很多公共地方,方便很多。

1. 抽象公司職員類

public abstract class Corp {
	//公司每個人都有名稱
	private String name = "";
	//公司每個人都有職位
	private String position = "";
	//公司每個人都有薪水
	private int salary = 0;
	public Corp(String name, String position, int salary) {
		this.name = name;
		this.position = position;
		this.salary = salary;
	}
	//獲取員工資訊
	public String getInfo(){
		String info = "";
		info = "名稱:"+this.name;
		info = info + "\t職位:"+this.position;
		info = info + "\t薪水:"+this.salary;
		return info;
	}
}
2. 樹葉節點
public class Leaf extends Corp{
	//就寫一個建構函式,這個是必須 的
	public Leaf(String name, String position, int salary) {
		super(name, position, salary);
	}
}
3. 樹枝節點 
public class Branch extends Corp{
	//儲存子節點的資訊
	private ArrayList subordinateList = new ArrayList();
	//建構函式是必須 的
	public Branch(String name, String position, int salary) {
		super(name, position, salary);
	}
	//增加一個下屬,可能 是小頭目,也可能是個小兵
	public void addSubordinate(Corp corp) {
		this.subordinateList.add(corp);
	}
	//我有哪些下屬
	public ArrayList<Corp> getSubordinate() {
		return this.subordinateList;
	}
}
4. 稍稍修改場景類

程式碼太長,同上例,修改其中部分方法

//遍歷整棵樹,只要給我根節點,我就能遍歷出所有的節點
public static String getTreeInfo(Branch root){
	List<Corp> subordinateList = root.getSubordinate();
	String info = "";
	for(Corp s : subordinateList){
		if(s instanceof Leaf){
			info = info + s.getInfo() + "\n";
		}else{	//是個小頭目
			info = info + s.getInfo() + "\n" + getTreeInfo((Branch)s);
		}
	}
	return info;
}
三、組合模式定義 Component抽象構件角色:定義參加組合物件的共有方法和屬性,可以定義一些預設的行為或屬性,比如我們例子中的getInfo就封裝到了抽象類中

Leaf葉子構件:葉子物件,其下再也沒有其它分支,也就是遍歷的最小單位。

Composite樹枝構件:樹枝物件,作用是組合樹枝節點和葉子節點形成一個樹形結構。

1. 抽象構件

public abstract class Component {
	//個體和整體都具有的共享
	public void doSomething(){
		//編寫業務邏輯
	}
}
2. 樹枝構件
public class Composite extends Component{
	//構件容器
	private List<Component> componentArrayList = new ArrayList<Component>();
	//增加一個葉子構件或樹枝構件
	public void add(Component component){
		this.componentArrayList.add(component);
	}
	//刪除一個葉子構件或樹枝構件
	public void remove(Component component){
		this.componentArrayList.remove(component);
	}
	//獲得分支下的所有葉子構件和樹枝構件
	public List<Component> getChildren(){
		return this.componentArrayList;
	}
}
3. 樹葉構件
public class Leaf extends Component{
	/*
	 * 可以覆寫父類方法
	 * public void doSomething(){
	 * 
	 * }
	 */
}
4. 場景類
public class Client {
	public static void main(String[] args) {
		//建立一個根節點
		Composite root = new Composite();
		root.doSomething();
		//建立一個樹枝構件
		Composite branch = new Composite();
		//建立一個葉子節點 
		Leaf leaf = new Leaf();
		//建立整體
		root.add(branch);
		branch.add(leaf);
	}
	//通過遞迴遍歷樹
	public static void display(Composite root){
		for(Component c:root.getChildren()){	//葉子節點
			if(c instanceof Leaf){
				c.doSomething();
			}else{	//樹枝節點 
				display((Composite)c);
			}
		}
	}
}
四、組合模式的應用

1.優點:

高層模組呼叫簡單:一棵樹形機構中的所有節點都是Component,區域性和整體對呼叫者來說沒有任何區別,也就是說,高層模組不必關心自己處理的是單個物件還是整個組合結構,簡化了高層模組的程式碼。

節點自由增加:使用組合模式後,如果想增加一個樹枝節點、樹葉節點都很容易,只要找到它的父節點就成,符合開閉原則。

2. 缺點

看到在我們的場景類中定義,提到樹葉和樹枝使用時的定義了嗎?直接使用了實現類!這在面向介面程式設計上是很不恰當的,與依賴倒置原則衝突,讀者在使用時要考慮清楚,它限制了你介面的影響範圍

3. 使用用場景

1)維護和展示部分-整體關係的場景,如樹形選單、檔案和資料夾管理。

2)從一個整體中能夠獨立出部分模組或功能的場景。

4. 組合模式的注意事項

只要是樹形結構,就要考慮使用組合模式,這個一定要記住,只要是要體現區域性和整體的關係的時候,而且這種關係還可能比較深,考慮一下組合模式吧
五、組合模式的擴充套件
1. 真實的組合模式

上述Client程式沒沒有改變多少,樹的組裝是跑不了的,但樹的組裝並不是像例子中的new,而是一般先有一張資料庫的表,這張資料表定義了一個樹形結構,我們把它讀取出來,然後展現到前臺上,用for迴圈加上遞迴就可以完成這個讀取,

2. 透明的組合模式(一般用安全模式就好)

我們上面的例子是安全模式,下面將下透明模式,透明模式是把用來組合使用的方法放到抽象中,比如add()、remove()以及getChildren等方法(),不管葉子物件不是樹枝物件都有相同的結構,通過判斷是getChildren的返回值確認是葉子節點 不是樹枝節點,如果處理不當會在執行期出現錯誤,所以建議用上述例子中的安全模式。

1) 抽象構件

public abstract class Component {
	//個體和整體都具有的共享
	public void doSomething(){
		//編寫業務邏輯
	}
	//增加一個葉子構件或樹枝構件
	public abstract void add(Component component);
	//刪除一個葉子構件或樹枝構件
	public abstract void remove(Component component);
	//獲得分支下的所有葉子構件和樹枝構件
	public abstract ArrayList<Component> getChildren();
}
2) 樹葉節點 
public class Leaf extends Component{
	public void add(Component component) {
		//空實現,直接拋一個“不支援請求”異常
		throw new UnsupportedOperationException();
	}
	public void remove(Component component) {
		//空實現,直接拋一個“不支援請求”異常
		throw new UnsupportedOperationException();
	}
	public ArrayList<Component> getChildren() {
		//空實現,直接拋一個“不支援請求”異常
		throw new UnsupportedOperationException();
	}
}
3) 樹結構遍歷
public class Client {
	public static void main(String[] args) {
		
	}
	//通過遞迴遍歷樹
	public static void display(Component root){
		for(Component c:root.getChildren()){
			if(c instanceof Leaf){
				c.doSomething();
			}else{	//樹枝節點
				display(c);
			}
		}
	}
}
3. 組合模式的遍歷(獲取父節點)

上面例子是從上向下獲取子節點,如果我想獲取父節點,可以這樣做

1)抽象構件

public abstract class Corp {
	//公司每個人都有名稱
	private String name = "";
	//公司每個人都有職位
	private String position = "";
	//公司每個人都有薪水
	private int salary = 0;
	//父節點是誰
	private Corp parent = null;
	public Corp(String name, String position, int salary) {
		this.name = name;
		this.position = position;
		this.salary = salary;
	}
	//獲取員工資訊
	public String getInfo(){
		String info = "";
		info = "名稱:"+this.name;
		info = info + "\t職位:"+this.position;
		info = info + "\t薪水:"+this.salary;
		return info;
	}
	//設定父節點
	protected void setParent(Corp _parent){
		this.parent = _parent;
	}
	//得到父節點
	public Corp getParent(){
		return this.parent;
	}
}
2)樹枝構件
public class Branch extends Corp{
	//儲存子節點的資訊
	private ArrayList subordinateList = new ArrayList();
	//建構函式是必須 的
	public Branch(String name, String position, int salary) {
		super(name, position, salary);
	}
	//增加一個下屬,可能 是小頭目,也可能是個小兵
	public void addSubordinate(Corp corp) {
		corp.setParent(this);	//設定父節點 
		this.subordinateList.add(corp);
	}
	//我有哪些下屬
	public ArrayList<Corp> getSubordinate() {
		return this.subordinateList;
	}
}
六、最佳實踐

一般主頁左邊的導航選單或者有樹形結構的模組都可以考慮。

相關推薦

* 24設計模式——組合模式

將物件組合成樹形結構,以表示“部分-整體”的層次結構,使得使用者對單個物件和組合物件的使用具有一致性。 一、公司組織架構1(介面篇) 1. 公司人員介面 public interface ICorp { //獲取自己的資訊(每個員工都有資訊,你想隱藏,門兒都沒有)

Java中的24設計模式與7大原則

工廠模式 職責 需要 占位符 ati gre template 層次 cto 一、創建型模式 1、抽象工廠模式(Abstract factory pattern): 提供一個接口, 用於創建相關或依賴對象的家族, 而不需要指定具體類.2、生成器模式(Builder pat

OOP 思想 和 設計原則 及24設計模式

父類 分組 策略 結構 並且 實例 適配器模式 closed 不同的 oop思想:封裝、繼承、多態 把組件實現和接口分開,並且讓組件具有多態性 面向對象編程是一種解決軟件復用的設計和編程方法,這種方法把軟件中相近相似的操作邏輯和操作應用數據

Python七大原則,24設計模式

虛擬 esp 成對 adapt 責任 低耦合 命令模式 兼容 facade 七大設計原則: 1、單一職責原則【SINGLE RESPONSIBILITY PRINCIPLE】:一個類負責一項職責. 2、裏氏替換原則【LISKOV SUBSTITUTION PRINCIPLE

(轉載)24設計模式--原型模式【Prototype Pattern】

dex clone() new t 分享圖片 object try arr 建立 不同 今天我們來講原型模式,這個模式的簡單程度是僅次於單例模式和叠代器模式,非常簡單,但是要使用好這個模式還有很多註意事項。我們通過一個例子來解釋一下什麽是原型模式。   現在電子賬單越來越流

設計模式大雜燴(24設計模式的總結以及學習設計模式的幾點建議)

  作者:zuoxiaolong8810(左瀟龍),轉載請註明出處,特別說明:本博文來自博主原部落格,為保證新部落格中博文的完整性,特複製到此留存,如需轉載請註明新部落格地址即可。            迄今為止

24設計模式與6大原則

外部與一個子系統的通訊必須通過一個統一的門面(Facade)物件進行,這就是門面模式。 醫院的例子 用一個例子進行說明,如果把醫院作為一個子系統,按照部門職能,這個系統可以劃分為掛號、門診、劃價、化驗、收費、取藥等。看病的病人要與這些部門打交道,就如同一個子系統的客戶端與一個子系統的各個類打交道一

* 24設計模式——享元模式

核心:使用共享物件可有效地支援大量的細粒度的物件。運用共享技術,使得一些細粒度的物件可以共享。 一、報名系統crash多臺機器 報考系統crash,原因是使用了工廠模式來獲取物件,在大訪問量100萬時,就會有100萬個物件,因為JVM回收不及時,導致記憶體OutOfMemo

24設計模式大全-牛人詳解

Adapter模式和Bridge模式具有一些共同的特徵。它們都給另一物件提供了一定程度上的間接性,因而有利於系統的靈活性。它們都涉及到從自身以外的一個介面向這個物件轉發請求。這些模式的不同之處主要在於它們各自的用途。Bridge模式主要是為了解決兩個已有介面之間不匹配的問題。它不考慮這些介面是怎樣實現的,也不

24設計模式-抽象工廠模式(6)

好了,我們繼續上一節課,上一節講到女媧造人,人是造出來了,世界時熱鬧了,可是低頭一看,都是清一色的型別,缺少關愛、仇恨、喜怒哀樂等情緒,人類的生命太平淡了,女媧一想,猛然一拍腦袋,Shit!忘記給人類定義性別了,那怎麼辦?抹掉重來,然後就把人類重新洗牌,準備重新開始製造人類。

Python中的七大設計原則 + 24設計模式

七大設計原則:  1、單一職責原則【SINGLE RESPONSIBILITY PRINCIPLE】:一個類負責一項職責.  2、里氏替換原則【LISKOV SUBSTITUTION PRINCIPLE】:繼承與派生的規則.(子類可替換父類)  3、依賴倒轉原則【D

24設計模式複習總結

Factory Pattern(工廠模式):1. 建立物件的介面,封裝物件的建立;2. 使具體化類的工作延遲到子類中。(維護一類物件) AbstractFactory Pattern(抽象工廠 模型):該模式將一組物件的建立封裝到一個用於建立物件的類中。(解決的問題:要建

24設計模式及案例

建立型模式 結構型模式 介面卡模式 介紹 裝飾器模式 介紹 代理模式 介紹 外觀模式 介紹 橋接模式 介紹 組合模式 介紹 享元模式 介紹 行為型模式 策略模式 介紹 模板模式 介紹 觀察者模式

JAVA的23設計模式---組合模式

概要: 該文章參考了《設計模式之禪》一書及一些前輩的部落格文章 1.該文章闡述了組合模式的基礎原理及示例程式碼; 2.該文章適合初學設計模式的技術人員研習; 3.該文章有許多不足之處,請各位大咖指正,噴子繞道; 正文: 組合模式(合成模式、部分-整體

24設計模式優缺點及適用場景#工廠方法模式

產品 抽象 彌補 用戶 裏氏替換原則 一個 延伸 無需 可擴展 創建型#工廠方法模式 概述:   工廠方法是簡單工廠模式的延伸,它繼承了簡單工廠模式的優點,同時還彌補了簡答工廠模式的不足。工廠方法是最常用的設計模式之一,很多開源框架和API類庫的核心模式。 優點:

24設計模式優缺點及適用場景#抽象工廠模式

隔離 並且 strong 穩定 改變 優點 功能 方式 ron 創建型#抽象工廠模式 概述:   抽象工廠方法是工廠方法模式的延伸,它提供了功能更為強大的工廠類並且具備較好的可擴展性; 優點:   1、抽象工廠模式隔離了具體類的生成,使得客戶端並不需要知道什麽被創建

設計模式-組合模式

設計模式 組合模式 abstract class Component { protected string name; public Component(string _name) { name = _name;

重走Java設計模式——組合模式(Composite Pattern)

組合模式 定義 組合模式(Composite Pattern),又叫部分整體模式,是用於把一組相似的物件當作一個單一的物件。組合模式依據樹形結構來組合物件,用來表示部分以及整體層次。這種型別的設計模式屬於結構型模式,它建立了物件組的樹形結構。 這種模式建立了一個包含自己物

設計模式 --- 組合模式

1.定義 將物件組合成樹形結構以表示“部分-整體”的層次結構,使得使用者對單個物件和組合物件的使用具有一致性。   2.使用場景 表示物件的整體-部分層次結構時 從一個整體能夠獨立出部分模組或功能的場景   3.簡單實現 以作業系統的檔案系統為例。

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

    組合模式是構造型模式的一種。通過遞迴手段來構造樹形的物件結構,並可以通過一個物件來訪問整個物件樹   角色和職責: 就是資料夾那種形式,樹形   UML圖:   具體程式碼: import java.util.List