1. 程式人生 > 其它 >設計模式 -> 結構型 - 組合(Composite)

設計模式 -> 結構型 - 組合(Composite)

組合模式(composite pattern): 允許你將物件組合成樹形結構來表現"整體/部分"層次結構. 組合能讓客戶以一致的方式處理個別對象以及物件組合。

1. 意圖

將物件組合成樹形結構來表示“整體/部分”層次關係,允許使用者以相同的方式處理單獨物件和組合物件。

3. 類圖

元件(Component)類是組合類(Composite)和葉子類(Leaf)的父類,可以把組合類看成是樹的中間節點。 組合物件擁有一個或者多個元件物件,因此組合物件的操作可以委託給元件物件去處理,而元件物件可以是另一個組合物件或者葉子物件。

3. 實現

public abstract class Component {
    protected String name;

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

    public void print() {
        print(0);
    }

    abstract void print(int level);

    abstract public void add(Component component);

    abstract public void remove(Component component);
}
public class Composite extends Component {

    private List<Component> child;

    public Composite(String name) {
        super(name);
        child = new ArrayList<>();
    }

    @Override
    void print(int level) {
        for (int i = 0; i < level; i++) {
            System.out.print("--");
        }
        System.out.println("Composite:" + name);
        for (Component component : child) {
            component.print(level + 1);
        }
    }

    @Override
    public void add(Component component) {
        child.add(component);
    }

    @Override
    public void remove(Component component) {
        child.remove(component);
    }
}
public class Leaf extends Component {
    public Leaf(String name) {
        super(name);
    }

    @Override
    void print(int level) {
        for (int i = 0; i < level; i++) {
            System.out.print("--");
        }
        System.out.println("left:" + name);
    }

    @Override
    public void add(Component component) {
        throw new UnsupportedOperationException(); // 犧牲透明性換取單一職責原則,這樣就不用考慮是葉子節點還是組合節點
    }

    @Override
    public void remove(Component component) {
        throw new UnsupportedOperationException();
    }
}
public class Client {
    public static void main(String[] args) {
        Composite root = new Composite("root");
        Component node1 = new Leaf("1");
        Component node2 = new Composite("2");
        Component node3 = new Leaf("3");
        root.add(node1);
        root.add(node2);
        root.add(node3);
        Component node21 = new Leaf("21");
        Component node22 = new Composite("22");
        node2.add(node21);
        node2.add(node22);
        Component node221 = new Leaf("221");
        node22.add(node221);
        root.print();
    }
}
Composite:root
--left:1
--Composite:2
----left:21
----Composite:22
------left:221
--left:3