設計模式之組合模式

組合模式可以用在樹狀結構的組合當中,把上下級對象抽象出一個基類,通過這個基類可以實現帶分支的父節點,也可以實現單個末端節點。

基類用來提供添加和刪除子分支的方法,儘管末端節點不需要添加分支,但還是把編輯子分支的方法統一放到基類當中省去判斷節點種類。每個節點的職責可以直接抽象,或者添加一個默認實現:

public abstract class Component {
    String name;

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

    abstract void add(Component component);

    abstract void remove(Component component);

    void function(int level) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < level; i++) {
            sb.append("    ");
        }
        sb.append(name);
        System.out.println(sb.toString());
    }
}

最基本的可以只定義兩種類型的實現:
帶有分支的實現:

public class ParentCompany extends Component {
    private List<Component> list = new ArrayList<>();

    public ParentCompany(String name) {
        super(name);
    }

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

    @Override
    void remove(Component component) {
        list.remove(component);
    }

    @Override
    void function(int level) {
        super.function(level);
        level++;
        for (int i = 0; i < list.size(); i++) {
            list.get(i).function(level);
        }
    }
}

不帶分支的實現:

public class EndCompany extends Component {

    public EndCompany(String name) {
        super(name);
    }

    @Override
    void add(Component component) {
    }

    @Override
    void remove(Component component) {
    }
}

測試類:

public class Main {

    public static void main(String[] args) {

        final ParentCompany country = new ParentCompany("國家級總公司");
        final ParentCompany province = new ParentCompany("省級總公司");
        final EndCompany provinceEnd = new EndCompany("省級辦事處");
        final ParentCompany city = new ParentCompany("市級總公司");
        final EndCompany cityEnd1 = new EndCompany("市級辦事處1");
        final EndCompany cityEnd2 = new EndCompany("市級辦事處2");
        final EndCompany townEnd = new EndCompany("鎮級辦事處");

        country.add(province);
        country.add(provinceEnd);
        province.add(city);
        province.add(cityEnd1);
        province.add(cityEnd2);
        city.add(townEnd);

        country.function(0);
    }
}

輸出:

國家級總公司
    省級總公司
        市級總公司
            鎮級辦事處
        市級辦事處1
        市級辦事處2
    省級辦事處

對於更復雜的情況可以進一步派生不同的實現,細分更多的分支和終端節點。

發佈了73 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章