組合模式也叫合成模式,又叫樹形模式,就是把部份和整體的關系用樹形結構來表示,是的客戶端對單個對象和組合對象的使用具有1致性,可以看出,這里的部份和整體之間在功能上是類似的,對這類類似性,通常可以采取繼承的方式來實現,根據面向對象的設計原則,盡可能使用組合而非繼承,因此合成模式也是繼承的1個替換方案。
組合模式主要3個部份:抽象類,葉子類,父類。
抽象構件角色(component):這是1個抽象角色,它給參加組合的定義出公共的接口和默許的行動。可以來管理所有的子對象。在安全式的合成模式里面,構件角色其實不是定義管理子對象的方法,這1定義由樹形構件對象給出。
樹葉構件角色(Leaf):在組合樹中表示葉節點對象,葉節點沒有子節點。并在組合中定義圖元對象的行動。
樹枝構件角色(Composite):定義有子部件的那些部件的行動。存儲子部件。在Component接口中實現與子部件有關的操作。
客戶角色(Client):通過component接口操縱組合部件的對象。
(1) 定義了包括基本對象和組合對象的類層次結構 基本對象可以被組合成更復雜的組合對象,而這個組合對象又可以被組合,這樣不斷的遞歸下去。客戶代碼中,任何用到 基本對象的地方都可使用組合對象。
(2)簡化客戶代碼 客戶可以1致地使用組合結構和單個對象。通經常使用戶不知道 (也不關心)處理的是1個葉節點還是1個組合組件。這就簡化了客戶代碼 , 由于在定義組合的那些類中不需要寫1些充斥著選擇語句的函數。
(3)使得更容易增加新類型的組件 新定義的Composite或Leaf子類自動地與已有的結構和客戶代碼1起工作,客戶程序不需因新的Component類而改變。
(4)使你的設計變得更加1般化 容易增加新組件也會產生1些問題,那就是很難限制組合中的組件。有時你希望1個組合只能有某些特定的組件。使用Composite時,你不能依賴類型系統施加這些束縛,而必須在運行時刻進行檢查。
舉例:生活中常常用到的加減乘除運算,有時還要對基本運算后的數據再次運算,下面使用組合模式實現。
SalaryComputer.java
package com.devin.composite;
/**
* @author 作者:ldw E-mail: csu.ldw@csu.edu.cn
* @version 創建時間:2015年4月25日 上午9:16:12
* 類說明
*/
public interface SalaryComputer {
public double computer(double m,double n);
}
加法運算類代碼:
Add.java
package com.devin.composite;
/**
* @author 作者:ldw E-mail: csu.ldw@csu.edu.cn
* @version 創建時間:2015年4月25日 上午9:16:47
* 類說明
*/
public class Add implements SalaryComputer{
@Override
public double computer(double m, double n) {
return m+n;
}
}
減法類實現代碼:
Subtract.java
package com.devin.composite;
/**
* @author 作者:ldw E-mail: csu.ldw@csu.edu.cn
* @version 創建時間:2015年4月25日 上午9:16:47
* 類說明
*/
public class Subtract implements SalaryComputer{
@Override
public double computer(double m, double n) {
return m-n;
}
}
乘法類實現代碼:
Multiplication.java
package com.devin.composite;
/**
* @author 作者:ldw E-mail: csu.ldw@csu.edu.cn
* @version 創建時間:2015年4月25日 上午9:16:47
* 類說明
*/
public class Multiplication implements SalaryComputer{
@Override
public double computer(double m, double n) {
return m*n;
}
}
除法類實現代碼:
Division.java
package com.devin.composite;
/**
* @author 作者:ldw E-mail: csu.ldw@csu.edu.cn
* @version 創建時間:2015年4月25日 上午9:16:47
* 類說明
*/
public class Division implements SalaryComputer{
@Override
public double computer(double m, double n) {
return m/n;
}
}
組合類運算代碼:
Composite.java
package com.devin.composite;
import java.util.ArrayList;
import java.util.List;
/**
* @author 作者:ldw E-mail: csu.ldw@csu.edu.cn
* @version 創建時間:2015年4月25日 上午9:18:20
* 類說明
*/
public class Composite implements SalaryComputer {
private List<SalaryComputer> list = new ArrayList<SalaryComputer>();
public void add(SalaryComputer salaryComputer){
list.add(salaryComputer);
}
public void remove(SalaryComputer salaryComputer){
list.remove(salaryComputer);
}
@Override
public double computer(double m, double n) {
double count = 0;
for (int i = 0; i < list.size(); i++) {
SalaryComputer salaryComputer = (SalaryComputer)list.get(i);
count+= salaryComputer.computer(m, n);
}
System.out.println("m=" + m + ",n="+ n +" 計算后的結果為"+count);
return count;
}
}
客戶端代碼:
Client.java
package com.devin.composite;
/**
* @author 作者:ldw E-mail: csu.ldw@csu.edu.cn
* @version 創建時間:2015年4月25日 上午9:23:46
* 類說明
*/
public class Client {
public static void main(String[] args) {
Composite salaryComputer = new Composite();
salaryComputer.add(new Division());
salaryComputer.computer(2000, 5);
}
}
m=1000.0,n=5.0 計算后的結果為200.0
(1)裝潢模式(Decorator模式)常常與Composite模式1起使用。當裝潢和組合1起使用時,它們通常有1個公共的父類。因此裝潢必須支持具有 Add、Remove和GetChild 操作的Component接口。
(2)享元模式(Flyweight)模式讓你同享組件,但不再能援用他們的父部件。
(3)迭代器模式(Itertor)可用來遍歷Composite。
(4)視察者模式(Visitor)將本來應當散布在Composite和L e a f類中的操作和行動局部化。
JUnit單元測試框架等。
下一篇 機房收費系統--設計模式思考