二十三種設計模式分類
一、概述
組合(Composite
)模式的定義:有時又叫作部分-整體模式,它是一種將對象組合成樹狀的層次結構的模式,用來表示“部分-整體”的關係,使用戶對單個對象和組合對象具有一致的訪問性。
將對象組合成樹形結構以表示"部分-整體"的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。
優點
- 組合模式使得客戶端代碼可以一致地處理單個對象和組合對象,無須關心自己處理的是單個對象,還是組合對象,這簡化了客戶端代碼;
- 更容易在組合體內加入新的對象,客戶端不會因爲加入了新的對象而更改源代碼,滿足“開閉原則”;
缺點
- 設計較複雜,客戶端需要花更多時間理清類之間的層次關係;
- 不容易限制容器中的構件;
- 不容易用繼承的方法來增加構件的新功能;
場景
部分、整體場景,如樹形菜單,文件、文件夾的管理。
二、實現
1. 結構圖
組合模式包含以下主要角色:
- 抽象構件(
Component
)角色:它的主要作用是爲樹葉構件和樹枝構件聲明公共接口,並實現它們的默認行爲。在透明式的組合模式中抽象構件還聲明訪問和管理子類的接口;在安全式的組合模式中不聲明訪問和管理子類的接口,管理工作由樹枝構件完成。 - 樹葉構件(
Leaf
)角色:是組合中的葉節點對象,它沒有子節點,用於實現抽象構件角色中 聲明的公共接口。 - 樹枝構件(
Composite
)角色:是組合中的分支節點對象,它有子節點。它實現了抽象構件角色中聲明的接口,它的主要作用是存儲和管理子部件,通常包含Add()
、Remove()
、GetChild()
等方法。 - 透明方式:在該方式中,由於抽象構件聲明瞭所有子類中的全部方法,所以客戶端無須區別樹葉對象和樹枝對象,對客戶端來說是透明的。但其缺點是:樹葉構件本來沒有
Add()
、Remove()
及GetChild()
方法,卻要實現它們(空實現或拋異常),這樣會帶來一些安全性問題。
- 安全方式:在該方式中,將管理子構件的方法移到樹枝構件中,抽象構件和樹葉構件沒有對子對象的管理方法,這樣就避免了上一種方式的安全性問題,但由於葉子和分支有不同的接口,客戶端在調用時要知道樹葉對象和樹枝對象的存在,所以失去了透明性。
PS
:UML
結構圖可以參考,例子實現並不根據UML
圖來完成,靈活實現即可;
2. 透明式實現
- 抽象節點類
package cn.missbe.model.composite;
/**
* Copyright (c) 2020.
* Email: [email protected]
*
* @author lyg 2020/4/22 下午1:21
* description:
* 組合模式,適用於樹狀結構
**/
public abstract class AbstractNode {
String name;
AbstractNode(String name) {
this.name = name;
}
protected abstract void add(AbstractNode node);
protected abstract void remove(AbstractNode node);
public abstract void display(int depth);
}
- 分支節點
package cn.missbe.model.composite;
import java.util.ArrayList;
import java.util.List;
/**
* Copyright (c) 2020.
* Email: [email protected]
*
* @author lyg 2020/4/22 下午1:21
* description:
* Composite 組合子結點
**/
public class BranchNodeComposite extends AbstractNode {
private List<AbstractNode> children = new ArrayList<>();
BranchNodeComposite(String name) {
super(name);
}
@Override
public void add(AbstractNode node) {
children.add(node);
}
@Override
public void remove(AbstractNode node) {
children.remove(node);
}
@Override
public void display(int depth) {
for (int i = 0; i < depth; i++) {
System.out.print("----");
}
System.out.println(name);
for (AbstractNode c : children) {
c.display(depth + 1);
}
}
}
- 葉子節點
package cn.missbe.model.composite;
/**
* Copyright (c) 2020.
* Email: [email protected]
* @author lyg 2020/4/22 下午1:21
* description:
**/
public class LeafNode extends AbstractNode {
LeafNode(String name) {
super(name);
}
@Override
protected void add(AbstractNode node) {
System.out.println("cannot add..");
}
@Override
protected void remove(AbstractNode node) {
System.out.println("cannot remove..");
}
@Override
public void display(int depth) {
for (int i = 0; i < depth; i++) {
System.out.print("----");
}
System.out.println(name);
}
}
Main
主類
package cn.missbe.model.composite;
/**
* Copyright (c) 2020.
* Email: [email protected]
* @author lyg 2020/4/22 下午1:21
* description:
* 組合模式
**/
public class Main {
public static void main(String[] args) {
AbstractNode root = new BranchNodeComposite("root");
BranchNodeComposite chapter1 = new BranchNodeComposite("chapter1");
chapter1.add(new LeafNode("LeafNode C"));
chapter1.add(new LeafNode("LeafNode D"));
root.add(chapter1);
root.add(new LeafNode("LeafNode A"));
root.add(new LeafNode("LeafNode B"));
BranchNodeComposite chapter2 = new BranchNodeComposite("chapter2");
chapter2.add(new LeafNode("LeafNode C"));
chapter2.add(new LeafNode("LeafNode D"));
root.add(chapter2);
root.display(0);
}
}