• <menu id="gyiem"><menu id="gyiem"></menu></menu>
  • <menu id="gyiem"><code id="gyiem"></code></menu>

    Java設計模式(五) 組合模式

    原創文章,轉載請務必將下面這段話置于文章開頭處(保留超鏈接)。
    本文轉發自技術世界原文鏈接 http://www.luozeyang.com/design_pattern/composite/

    組合模式介紹

    組合模式定義

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

    組合模式類圖

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

    組合模式角色劃分

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

    組合模式實例

    實例介紹

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

    實例類圖

    組合模式實例類圖如下(點擊可查看大圖)
    Composite pattern example class diagram

    實例解析

    本例代碼可從作者Github下載

    抽象組件

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    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);
    }

    }

    簡單組件(部門)

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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());
    }

    }

    復合組件(公司)

    復合組件在自身對消息作出響應后,還須通知其下所有子組件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    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設計模式系列

    郭俊 Jason wechat
    歡迎關注作者微信公眾號【大數據架構】
    您的贊賞將支持作者繼續原創分享
    速赢彩app 吴忠 | 大同 | 五家渠 | 青海西宁 | 湖州 | 佛山 | 白银 | 淄博 | 河南郑州 | 贵州贵阳 | 龙岩 | 赤峰 | 吉林 | 衡阳 | 聊城 | 汉川 | 信阳 | 醴陵 | 来宾 | 安阳 | 新泰 | 贺州 | 伊犁 | 济南 | 海西 | 宜都 | 新疆乌鲁木齐 | 上饶 | 忻州 | 嘉峪关 | 广元 | 肇庆 | 防城港 | 辽宁沈阳 | 大连 | 金昌 | 云浮 | 烟台 | 漯河 | 馆陶 | 和田 | 扬中 | 嘉善 | 临沂 | 醴陵 | 石河子 | 醴陵 | 蓬莱 | 博尔塔拉 | 阜阳 | 儋州 | 启东 | 清远 | 贺州 | 任丘 | 库尔勒 | 嘉峪关 | 十堰 | 平凉 | 菏泽 | 铜陵 | 黔南 | 莒县 | 唐山 | 德清 | 乐山 | 揭阳 | 兴安盟 | 鸡西 | 防城港 | 锡林郭勒 | 淮北 | 四川成都 | 陵水 | 抚州 | 丽水 | 昭通 | 偃师 | 凉山 | 诸暨 | 肇庆 | 鹰潭 | 垦利 | 孝感 | 潜江 | 铜川 | 如东 | 舟山 | 惠东 | 宜都 | 烟台 | 黔南 | 天长 | 忻州 | 张家界 | 安康 | 抚顺 | 海西 | 海拉尔 | 齐齐哈尔 | 攀枝花 | 德宏 | 常德 | 单县 | 临猗 | 万宁 | 临沧 | 肥城 | 绵阳 | 忻州 | 西双版纳 | 黑河 | 明港 |