設計模式——組合設計模式

前言

     需求中是體現部分與總體層次的結構時,以及你但願用戶能夠忽略組合對象與單個對象的不一樣,統一地使用組合結構中的全部對象時,就應該考慮使用組合模式了——《大話設計模式》html

    能夠用於樹結構的數據上,好比公司層級,樹形文件系統等。java

實現

     公司架構是總公司下有人力資源部和財務部以及分公司,分公司下有人力資源部和財務部已經下屬的辦事處,辦事處下屬也有人力資源和財務部,對公司架構能夠分析總結出,一共分爲實體公司部門(分支節點),好比分公司、總公司、辦事處,人力資源部門和財務部(葉子節點),各辦事處、分公司都有單獨設置。編程

      首先抽象一層公司的描述:設計模式

public abstract class Company {
    protected String name;

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

    public abstract void add(Company c);
    public abstract void remove(Company c);
    public abstract void display(int depth); //顯示
    public abstract void lineOfDuty(); //履行職責
}

    實現一個普通的公司描述:架構

public class ConcreteCompany extends Company {

    private List<Company> children = new ArrayList();

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

    @Override
    public void add(Company c) {
        children.add(c);
    }

    @Override
    public void remove(Company c) {
        children.remove(c);
    }

    @Override
    public void display(int depth) {
        Printer.print(depth, this.name);
        for (Company c : children) {
            c.display(depth + 2);
        }
    }

    @Override
    public void lineOfDuty() {
        for (Company c : children) {
            c.lineOfDuty();
        }
    }
}

      人力資源和財務部的實現:app

public class HrDepartment extends Company {
    public HrDepartment(String name) {
        super(name);
    }

    @Override
    public void add(Company c) {

    }

    @Override
    public void remove(Company c) {

    }

    @Override
    public void display(int depth) {
        Printer.print(depth,this.name);
    }

    @Override
    public void lineOfDuty() {
        System.out.println(String.format("%s 員工招聘培訓管理", this.name));
    }
}
public class FinanceDepartment extends Company {
    public FinanceDepartment(String name) {
        super(name);
    }

    @Override
    public void add(Company c) {

    }

    @Override
    public void remove(Company c) {

    }

    @Override
    public void display(int depth) {
        Printer.print(depth, this.name);
    }

    @Override
    public void lineOfDuty() {
        System.out.println(String.format("%s 公司財務收支管理", this.name));
    }
}

 另外增長一個打印的輔助工具類:ide

public class Printer {

    public static void print(int dept,String label) {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < dept; i++) {
            builder.append(" - ");
        }
        System.out.println(builder.toString() + label);
    }
}

運行上述的例子:工具

@Test
    public void testComposite(){
        ConcreteCompany root = new ConcreteCompany("北京總公司");
        root.add(new HrDepartment("總公司人力資源部"));
        root.add(new FinanceDepartment("總公司財務部"));

        ConcreteCompany comp = new ConcreteCompany("上海華東分公司");
        comp.add(new HrDepartment("華東分公司人力資源部"));
        comp.add(new FinanceDepartment("華東分公司財務部"));
        root.add(comp);

        ConcreteCompany comp1 = new ConcreteCompany("南京辦事處");
        comp1.add(new HrDepartment("南京辦事處人力資源部"));
        comp1.add(new FinanceDepartment("南京辦事處財務部"));
        comp.add(comp1);

        ConcreteCompany comp2 = new ConcreteCompany("杭州辦事處");
        comp2.add(new HrDepartment("杭州辦事處人力資源部"));
        comp2.add(new FinanceDepartment("杭州辦事處財務部"));
        comp.add(comp2);

        root.display(1);

        root.lineOfDuty();
    }

運行結果爲:ui

- 北京總公司
 -  -  - 總公司人力資源部
 -  -  - 總公司財務部
 -  -  - 上海華東分公司
 -  -  -  -  - 華東分公司人力資源部
 -  -  -  -  - 華東分公司財務部
 -  -  -  -  - 南京辦事處
 -  -  -  -  -  -  - 南京辦事處人力資源部
 -  -  -  -  -  -  - 南京辦事處財務部
 -  -  -  -  - 杭州辦事處
 -  -  -  -  -  -  - 杭州辦事處人力資源部
 -  -  -  -  -  -  - 杭州辦事處財務部
總公司人力資源部 員工招聘培訓管理
總公司財務部 公司財務收支管理
華東分公司人力資源部 員工招聘培訓管理
華東分公司財務部 公司財務收支管理
南京辦事處人力資源部 員工招聘培訓管理
南京辦事處財務部 公司財務收支管理
杭州辦事處人力資源部 員工招聘培訓管理
杭州辦事處財務部 公司財務收支管理

Process finished with exit code 0

總結

組合模式的優勢:this

  1. 能夠清楚地定義分層次的複雜對象,表示對象的所有或部分層次,使得增長新構件也更容易。
  2. 客戶端調用簡單,客戶端能夠一致的使用組合結構或其中單個對象。
  3.  定義了包含葉子對象和容器對象的類層次結構,葉子對象能夠被組合成更復雜的容器對象,而這個容器對象又能夠被組合,這樣不斷遞歸下去,能夠造成複雜的樹形結構。
  4. 更容易在組合體內加入對象構件,客戶端沒必要由於加入了新的對象構件而更改原有代碼。

組合模式的缺點:

  1. 使設計變得更加抽象,對象的業務規則若是很複雜,則實現組合模式具備很大挑戰性,並且不是全部的方法都與葉子對象子類都有關聯。
  2. 增長新構件時可能會產生一些問題,很難對容器中的構件類型進行限制。

在如下狀況下可使用組合模式:

  1. 須要表示一個對象總體或部分層次,在具備總體和部分的層次結構中,但願經過一種方式忽略總體與部分的差別,能夠一致地對待它們。
  2. 讓客戶可以忽略不一樣對象層次的變化,客戶端能夠針對抽象構件編程,無須關心對象層次結構的細節。
  3. 對象的結構是動態的而且複雜程度不同,但客戶須要一致地處理它們。

本文參考了《大話設計模式》  和 https://www.cnblogs.com/Bobby0322/p/4191895.html

相關文章
相關標籤/搜索