1. 程式人生 > >Java設計模式(五) 多型的極致應用——組合模式

Java設計模式(五) 多型的極致應用——組合模式

組合模式介紹

組合模式定義

組合模式(Composite Pattern)將物件組合成樹形結構以表示“部分-整體”的層次結構。組合模式使得使用者可以使用一致的方法操作單個物件和組合物件。

組合模式類圖

組合模式類圖如下
Composite pattern class diagram

組合模式角色劃分

  • 抽象元件,如上圖中的Component
  • 簡單元件,如上圖中的SimpleComponent
  • 複合元件,如上圖中的CompositeComponent

組合模式例項

例項介紹

對於一家大型公司,每當公司高層有重要事項需要通知到總部每個部門以及分公司的各個部門時,並不希望逐一通知,而只希望通過總部各部門及分公司,再由分公司通知其所有部門。這樣,對於總公司而言,不需要關心通知的是總部的部門還是分公司。

例項類圖

組合模式例項類圖如下(點選可檢視大圖)
Composite pattern example class diagram

例項解析

本例程式碼可從作者Github下載

抽象元件

抽象元件定義了元件的通知介面,並實現了增刪子元件及獲取所有子元件的方法。同時重寫了hashCodeequales方法(至於原因,請讀者自行思考。如有疑問,請在評論區留言)。

package com.jasongj.organization;

import java.util.ArrayList;
import java.util.List;

public abstract class Organization {

  private List<Organization> childOrgs = new
ArrayList<Organization>(); private String name; public Organization(String name) { this.name = name; } public String getName() { return name; } public void addOrg(Organization org) { childOrgs.add(org); } public void removeOrg(Organization org) { childOrgs.remove(org); } public
List<Organization> getAllOrgs() { return childOrgs; } public abstract void inform(String info); @Override public int hashCode(){ return this.name.hashCode(); } @Override public boolean equals(Object org){ if(!(org instanceof Organization)) { return false; } return this.name.equals(((Organization) org).name); } }

簡單元件(部門)

簡單元件在通知方法中只負責對接收到訊息作出響應。

package com.jasongj.organization;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Department extends Organization{

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

  private static Logger LOGGER = LoggerFactory.getLogger(Department.class);

  public void inform(String info){
    LOGGER.info("{}-{}", info, getName());
  }

}

複合元件(公司)

複合元件在自身對訊息作出響應後,還須通知其下所有子元件

package com.jasongj.organization;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Company extends Organization{

  private static Logger LOGGER = LoggerFactory.getLogger(Company.class);

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

  public void inform(String info){
    LOGGER.info("{}-{}", info, getName());
    List<Organization> allOrgs = getAllOrgs();
    allOrgs.forEach(org -> org.inform(info+"-"));
  }

}

組合模式優缺點

組合模式優點

  • 高層模組呼叫簡單。組合模式中,使用者不用關心到底是處理簡單元件還是複合元件,可以按照統一的介面處理。不必判斷元件型別,更不用為不同型別元件分開處理。
  • 組合模式可以很容易的增加新的元件。若要增加一個簡單元件或複合元件,只須找到它的父節點即可,非常容易擴充套件,符合“開放-關閉”原則。

組合模式缺點

  • 無法限制組合元件中的子元件型別。在需要檢測元件型別時,不能依靠編譯期的型別約束來實現,必須在執行期間動態檢測。

組合模式與OOP原則

已遵循的原則

  • 依賴倒置原則(複合型別不依賴於任何具體的元件而依賴於抽象元件)
  • 迪米特法則
  • 里氏替換原則
  • 介面隔離原則
  • 單一職責原則
  • 開閉原則

未遵循的原則

  • NA

Java設計模式系列