設計模式之(八)組合模式(COMPOSITE)

初始印象

  在開發中存在不少總體和部分的關係,這個方式最大的體現就是樹形結構。組合模式就是爲了更好地解決這類業務場景的問題。先看下組合模式的定義:ide

  將對象組合成樹形結構以表示「總體—部分」的層次關係。組合模式使得用戶對單個對象和組合對象的使用具備一致性。從定義中能夠看出來組合二模式主要有兩點;  this

    一、總體 - 部分 之間業務結構用樹形表示。spa

    二、讓組合對象和各個對象的使用具備一致性。code

  

        總體和部分的結構在生活中太普遍了,好比國家行政級別  中國 ,***省,**市 。學校管級別、公司管理組織機構等,下面以公司組織機構爲例,來看看組合模式。對象

    

   根據這個公司組織結構的圖片,來引進助興結構的專業名詞:總經理稱之爲 root 根節點,財務經理、技術經理、開發組長稱之爲 樹枝節點(branch),財務專員、祕書稱之爲 葉子節點(leaf)。blog

        而具體到代碼的實現層面就是,組合模式的核心關鍵就是把這三個對象實現相同的接口,無論是在組件過程,仍是後面的遍歷,全部的節點都用相同的接口,使得對樹形結構的操做更加方便。繼承

  接着介紹組合模式的組成元素接口

  • Component:組合部件,爲的是給 root、branch、leaf 不一樣的節點提供統一的接口。
  • Composite:複合節點,就是實現 root、branch 的節點,也叫容器節點。
  • Leaf : 葉子節點,不能再有下屬節點。也叫簡單節點。

應用例子

     接下來吧上圖中例子實現如下,可以更直觀瞭解組合模式圖片

// 至關因而 Component
public abstract class  Zhiwei {
    protected String name;
    protected String position;
    protected float salary;
    
    public Zhiwei(String name,String position,float salary){
        this.name = name;
        this.position = position;
        this.salary = salary;
    }
    
    public abstract void addChild(Zhiwei zhiwei);
    
    public abstract void removeChild(Zhiwei zhiwei);
    
    public abstract void display(String empty);
    
}

//至關因而 Composite
public class LingDao extends Zhiwei {

    private ArrayList<Zhiwei> children = new ArrayList<Zhiwei>();
    
    public LingDao(String name,String position,float salary){
        super(name,position,salary);
    }
    
    @Override
    public  void addChild(Zhiwei zhiwei) {
        // TODO Auto-generated method stub
        children.add(zhiwei);
    }

    @Override
    public void removeChild(Zhiwei zhiwei) {
        // TODO Auto-generated method stub
        
        children.remove(zhiwei);
    }

    @Override
    public void display(String empty) {
        // TODO Auto-generated method stub
        System.out.println(empty+"職位:"+this.position+" 姓名:"+this.name+" 薪水:"+this.salary);
        for (Zhiwei zhiwei : children) {
            zhiwei.display(empty+"    ");
        }
        
    }

}

//普通職員
public class Leaf extends Zhiwei {

    public Leaf(String name, String position, float salary) {
        super(name, position, salary);
        
        // TODO Auto-generated constructor stub
    }

    @Override
    public void addChild(Zhiwei zhiwei) {
        // TODO Auto-generated method stub
        System.out.println("cannot add zhiwei to leaf");
    }

    @Override
    public void removeChild(Zhiwei zhiwei) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void display(String empty) {
        // TODO Auto-generated method stub
        System.out.println(empty+"職位:"+this.position+" 姓名:"+this.name+" 薪水:"+this.salary);
    }
}

//客戶端
public class Client {
    public static void main(String[] args) {
        Zhiwei leader = new LingDao("張無忌","總經理",100000);
        
        Zhiwei manager = new LingDao("楊逍", "技術經理", 50000);
        Zhiwei managerB = new LingDao("範瑤","財務經理",50000);
        Zhiwei managerC = new LingDao("吳勁草","技術組長",20000);
        
        Zhiwei Employee = new LingDao("小昭","祕書",8000);
        
        Zhiwei EmployeeA = new LingDao("天字門","財務A",5000);
        Zhiwei EmployeeX = new LingDao("地字門","財務B",5200);
        Zhiwei EmployeeC = new LingDao("風字門","開發A",8800);
        Zhiwei EmployeeD = new LingDao("雷字門","開發B",8400);
        
        leader.addChild(manager);
        leader.addChild(managerB);
        leader.addChild(Employee);
        
        manager.addChild(managerC);
        manager.addChild(EmployeeC);
        
        managerC.addChild(EmployeeD);
        
        leader.display("");
    }
}

/********************控制檯************************/

- 職位:總經理 姓名:張無忌 薪水:100000.0
     - 職位:技術經理 姓名:楊逍 薪水:50000.0
          - 職位:技術組長 姓名:吳勁草 薪水:20000.0
               - 職位:開發B 職位:雷字門 薪水:8400.0
          - 職位:開發A 姓名:風字門 薪水:8800.0
     - 職位:財務經理 姓名:範瑤 薪水:50000.0
          - 職位:財務A 姓名:風字門 薪水:5000.0
          - 職位:財務B 姓名:地字門 薪水:5200.0
     - 職位:祕書 姓名:小昭 薪水:8000.0

  經過這個例子能夠看出來,不一樣級別的節點經過同一接口在客戶端試用是很是方便的,調用的時候不用管他表明的是什麼節點。由於可以同一試用。只是在 leaf 級別的節點中,考慮 addChild 、removeChild 給出錯誤提示便可。開發

對模式的分析

  咱們進一步來分析組合模式的應用場景,除了在很明顯的樹形結構業務中用,在發揮咱們的發散能力,應該可以想到,只要擁有父子關係的場景中都是能夠用的好比窗體打開的父子窗口、各類單位的人事制度的組織結構、文件管理系統、軟件系統的樹形結構導航。

  在思考了組合模式的應用場景後,在考慮下組合模式的優點:

       一、定義了實現不一樣層次的對象的統一接口,對象行爲更具備一致性。使得客戶端調用比較簡單。

  二、實現了整個業務場景的類層級的所屬關係,經過類裏面的 list 來實現。

  三、類實現更具通常性,使得代碼更具備可擴展性。主要表如今新定義的 composite 和 leaf 繼承了統一的操做接口,客戶端就不用改變。

小結

  組合模式應用場景是具備父子結構的場景,典型的就是樹形結構。模式的本質就是對不一樣級別的節點對象引入統一的接口,對不一樣級別對象調用、操做具備了一致性。

相關文章
相關標籤/搜索