組合模式(Composite Pattern)

意圖

允許你將對象組合成樹形結構來表現“整體/部分”。組合能讓客戶以一致的方式處理個別對象以及對象組合。

動機

形如:有一個樹形結構的菜單,子菜單和可能還帶有菜單項的子菜單,那麼任何菜單都是一種“組合”。因爲它既可以包含其他菜單,也可以包含菜單項。我們可以使用組合模式設計、編碼,從而對整個菜單結構應用相同的操作。

適用性

組合模式主要的應用場景:

  • 在需要表示一個對象整體與部分的層次結構的場合。
  • 要求對用戶隱藏組合對象與單個對象的不同,用戶可以用統一的接口使用組合結構中的所有對象的場合。

結構

組合模式包含以下主要角色:

  • 抽象組件(Component):爲分支節點和葉子節點聲明公共接口,並實現其默認方法。在透明式的組合模式中抽象組件還聲明訪問和管理子類的接口;在安全式的組合模式中不聲明訪問和管理子類的接口,管理工作由分支節點完成。
  • 分支節點(Composite):有子節點,實現了抽象構件角色中聲明的接口,主要作用是存儲和管理子部件,包含 add()、remove()、getChild() 等方法。
  • 葉子節點(Leaf):沒有子節點,用於實現抽象構件角色中聲明的公共接口。

組合模式分爲透明式的組合模式和安全式的組合模式。

  • 透明式

  • 安全式

實現

以透明式爲例

// 抽象組件
public interface Component {

	void add(Component com);
	void remove(Component com);
	Component getChild(int i);
	void operation();
}

// 分支節點
public class Composite implements Component {

	private List<Component> children = new ArrayList<Component>(16);
	@Override
	public void add(Component com) {
		children.add(com);
	}
	@Override
	public void remove(Component com) {
		children.remove(com);
	}
	@Override
	public Component getChild(int i) {
		return children.get(i);
	}
	@Override
	public void operation() {
		for (Component c : children) {
			c.operation();
		}
	}
}

// 葉子節點
public class Leaf implements Component {
	
	private String name;

	public Leaf(String name) {
		this.name = name;
	}

	@Override
	public void add(Component com) {}

	@Override
	public void remove(Component com) {}

	@Override
	public Component getChild(int i) {
		return null;
	}

	@Override
	public void operation() {
		 System.out.println("葉子節點 "+name+" 被訪問。。。"); 
	}
}

//測試客戶端,透明方式的組合模式
public class TestClient {

	public static void main(String[] args) {
		Component c0 = new Composite();
		Component c1 = new Composite();
		Component leaf1 = new Leaf("leaf1");
		Component leaf2 = new Leaf("leaf2");
		Component leaf3 = new Leaf("leaf3");
		c0.add(leaf1);
		c0.add(c1);
		c1.add(leaf2);
		c1.add(leaf3);
		c0.operation();
	}
}

已知應用

  • javax.swing.JComponent#add(Component)
  • java.awt.Container#add(Component)
  • java.util.Map#putAll(Map)
  • java.util.List#addAll(Collection)
  • java.util.Set#addAll(Collection)

相關模式

參考資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章