什麼是組合模式?
組合模式的定義
Compose objects into tree structures to represent part-whole hierarchies.Composite lets clients treat individual objects and compositions of objects uniformly.
將對象組合成樹形結構以表示 “部分-整體” 的層次結構,使得用戶對單個對象和組合對象的使用具有一致性。
主要優缺點
優點:
當需要在組合內添加新對象的時候,不需要修改源碼,複合開閉原則。
對外提供的是同一個對象,使用起來不必關心使用的是單個對象還是組合對象。
缺點:
設計起來比較複雜,需要理清類之間的層次關係。
使用場景
系統對象之間存在整體–部分的關係,並有一定的相同行爲。(JAVA中的swing,公司組織架構等等)
組合模式的結構和實現
組合模式結構
抽象根角色(Component):定義系統層級之間的相同行爲,是樹枝和葉子構建角色的公共抽象接口。
樹枝角色(Composite):定義樹枝角色的行爲,可以存儲子節點,子節點可以是樹枝角色也可以是葉子角色,通過組合樹枝角色和葉子角色形成一個樹形結構。
葉子角色(Leaf):定義葉子角色的行爲,其下再無分支。
主要有兩種實現方式:透明性組合模式和安全性組合模式
透明性組合模式實現
在透明性組合模式當中,抽象根角色(Component)包含了樹枝角色和葉子角色的所有行爲。所以在葉子角色當中會存在樹枝角色的行爲,但是這些行爲葉子角色是不支持的。就違背了接口隔離原則。
public class ComponentTest {
public static void main(String[] args) {
// 創建一個根節點
Component root = new Composite("根節點");
// 創建樹枝節點
Component branchA = new Composite("---樹枝A");
Component branchB = new Composite("------樹枝B");
// 來一個葉子節點
Component leafA = new Leaf("------葉子A");
Component leafB = new Leaf("------葉子B");
Component leafC = new Leaf("---葉子C");
root.addChild(branchA);
root.addChild(leafC);
branchA.addChild(leafA);
branchA.addChild(branchB);
branchB.addChild(leafB);
String result = root.operation();
System.out.println(result);
}
// 抽象構建角色
static abstract class Component {
String name;
Component(String name) {
this.name = name;
}
public abstract String operation();
public boolean addChild(Component component) {
throw new UnsupportedOperationException("addChild not supported!");
}
public Component getChild(int index) {
throw new UnsupportedOperationException("getChild not supported!");
}
}
//樹枝構建角色
static class Composite extends Component {
private List<Component> childComponent;
public Composite(String name) {
super(name);
this.childComponent = new ArrayList<>();
}
@Override
public String operation() {
StringBuilder builder = new StringBuilder(this.name);
if(this.childComponent.size()>0){
for (Component component : this.childComponent) {
builder.append("\n");
builder.append(component.operation());
}
}
return builder.toString();
}
@Override
public boolean addChild(Component component) {
return this.childComponent.add(component);
}
@Override
public Component getChild(int index) {
return this.childComponent.get(index);
}
}
//葉子構建角色
static class Leaf extends Component {
public Leaf(String name) {
super(name);
}
@Override
public String operation() {
return this.name;
}
}
}
安全性組合模式實現
在安全性組合模式當中,抽象根角色(Component)包含了樹枝角色和葉子角色的公共行爲。在葉子角色當中就不再存在樹枝角色的行爲。
public class ComponentTest2 {
public static void main(String[] args) {
// 創建一個根節點
Composite root = new Composite("根節點");
// 創建樹枝節點
Composite branchA = new Composite("---樹枝A");
Composite branchB = new Composite("------樹枝B");
// 來一個葉子節點
Component leafA = new Leaf("------葉子A");
Component leafB = new Leaf("------葉子B");
Component leafC = new Leaf("---葉子C");
root.addChild(branchA);
root.addChild(leafC);
branchA.addChild(leafA);
branchA.addChild(branchB);
branchB.addChild(leafB);
String result = root.operation();
System.out.println(result);
}
// 抽象構建角色
static abstract class Component {
String name;
Component(String name) {
this.name = name;
}
public abstract String operation();
}
//樹枝構建角色
static class Composite extends Component {
private List<Component> childComponent;
public Composite(String name) {
super(name);
this.childComponent = new ArrayList<>();
}
@Override
public String operation() {
StringBuilder builder = new StringBuilder(this.name);
if(this.childComponent.size()>0){
for (Component component : this.childComponent) {
builder.append("\n");
builder.append(component.operation());
}
}
return builder.toString();
}
public boolean addChild(Component component) {
return this.childComponent.add(component);
}
public Component getChild(int index) {
return this.childComponent.get(index);
}
}
//葉子構建角色
static class Leaf extends Component {
public Leaf(String name) {
super(name);
}
@Override
public String operation() {
return this.name;
}
}
}