常用設計模式系列(十三)—組合模式
第一節
前言
hello大家好,今年已經過去了一半,年初立下的flag,不知道實現了沒有,你的flag改了多少次?無論自己的愿望是否完成,我們都應該懷揣著追逐夢想之心,去嘗試突破上一年的自我。我去年的flag雖然也沒有實現,但是自己努力去做了,結果其實并不重要,更不要成為自己內心阻撓自己努力的絆腳石,加油,年輕人!
今天學習對象結構型設計模式的最后一章:組合模式,組合模式可以理解為整體+部分,一個整體有多個部分組成,例如一個樹由多個主干組成,每個主干又有多個樹杈,每個樹杈又有多個樹葉。
第二節
組合模式
組合(Composite
Pattern)模式的定義:有時又叫作整體-部分(Part-Whole)模式,它是一種將對象組合成樹狀的層次結構的模式,用來表示“整體-部分”的關系,使用戶對單個對象和組合對象具有一致的訪問性,屬于結構型設計模式。組合模式一般是用來描述整體與部分的關系,我們可以把它應用到數據結構的樹形結構當中,頂層的節點就是根節點,根節點下面可以包含多個樹枝節點和多個葉子節點,樹枝節點下面又可以包含樹枝節點和葉子節點,類似于我們學習數據結構中的樹形結構。在組合模式中,整個樹形結構中的對象都屬于同一種類型,帶來的好處就是用戶不需要辨別是樹枝節點還是葉子節點,可以直接進行操作,給用戶的使用帶來極大的便利。
前兩天圣誕節,小張同學為了慶祝過節,跑到了大超市買了很多的菜與肉類,從超市出來,小張同學買了許多的物品,跟超市的售貨員要了很大的帶子,這個大袋子里裝了用中型號袋子裝的各種蔬菜、塑料包裝的肉卷,小袋子裝的散裝丸子和小袋子裝的火鍋底料,中型的帶子里又裝了許多小袋子,每個小袋子都是一種蔬菜,而小袋子裝的盒子里面有三個更小的盒子,每個盒子分別是雞肉卷、羊肉卷、肥牛卷。這種大袋子套中袋子和物品,中袋子又套小袋子和物品的場景,無論是大袋子還是小袋子還是蔬菜,都屬于物品,這種嵌套組合,就是組合模式。
第三節
代碼實現
1.編寫抽象構件
package com.yang.composite;/*** @ClassName Articles* @Description 抽象構件-物品* @Author IT小白架構師之路* @Date 2020/12/29* @Version 1.0**/
public interface Articles {//計算價格public float calculation();//展示內容方法public void show();
}
2.編寫樹枝角色
package com.yang.composite;import java.util.ArrayList;
import java.util.List;/*** @ClassName Bags* @Description 樹枝構件:袋子* @Author IT小白架構師之路* @Date 2020/12/29* @Version 1.0**/
public class Bags implements Articles {private String name; //名字private List<Articles> bags = new ArrayList<Articles>();public Bags(String name) {this.name = name;}public void add(Articles c) {bags.add(c);}public void remove(Articles c) {bags.remove(c);}public Articles getChild(int i) {return bags.get(i);}public float calculation() {float s = 0;for (Object obj : bags) {s += ((Articles) obj).calculation();}return s;}public void show() {for (Object obj : bags) {((Articles) obj).show();}}
}
3.編寫樹葉角色
package com.yang.composite;/*** @ClassName Goods* @Description 樹葉構件:商品* @Author IT小白架構師之路* @Date 2020/12/29 16:53* @Version 1.0**/
public class Goods implements Articles {private String name; //名字private int quantity; //數量private float unitPrice; //單價//構造方法public Goods(String name, int quantity, float unitPrice) {this.name = name;this.quantity = quantity;this.unitPrice = unitPrice;}public float calculation() {return quantity * unitPrice;}public void show() {System.out.println(name + "(數量:" + quantity + ",單價:" + unitPrice + "元)");}
}
4.編寫測試類
package com.yang.composite;/*** @ClassName Client* @Description 客戶端測試* @Author IT小白架構師之路* @Date 2020/12/29* @Version 1.0**/
public class Client {public static void main(String[] args) {float s = 0;Bags BigBag, mediumBag, smallRedBag, smallWhiteBag;Goods sp;BigBag = new Bags("大袋子");mediumBag = new Bags("中袋子");smallRedBag = new Bags("紅色小袋子");smallWhiteBag = new Bags("白色小袋子");sp = new Goods("菠菜", 2, 7.9f);smallRedBag.add(sp);sp = new Goods("火鍋底料", 1, 9.9f);smallRedBag.add(sp);sp = new Goods("羊肉", 2, 38);smallWhiteBag.add(sp);sp = new Goods("紅酒", 3, 180);smallWhiteBag.add(sp);sp = new Goods("鴨血", 1, 10);mediumBag.add(sp);mediumBag.add(smallRedBag);sp = new Goods("土豆", 1, 3);BigBag.add(sp);BigBag.add(smallWhiteBag);BigBag.add(mediumBag);System.out.println("您選購的商品有:");BigBag.show();s = BigBag.calculation();System.out.println("要支付的總價是:" + s + "元");}
}
5.運行結果如下
您選購的商品有:土豆(數量:1,單價:3.0元)
羊肉(數量:2,單價:38.0元)
紅酒(數量:3,單價:180.0元)
鴨血(數量:1,單價:10.0元)
菠菜(數量:2,單價:7.9元)
火鍋底料(數量:1,單價:9.9元)
要支付的總價是:654.7元
第四節
優缺點分析與適用場景
優點
1.組合模式使客戶端代碼可以統一且通用的處理單個對象和組合對象,無須關心自己處理的是單個對象,還是組合對象,簡化了調用者的邏輯
2.在組合體內部增加對象變得很輕松,不需要修改源代碼來增加新的對象.
缺點:
1.設計的過程中,要考慮滿足類之前的通用抽象性,否則無法使用組合模式
2.如果限制具體構建,則很難限制.
3.不容易使用繼承的方法來擴展新功能,只能使用別的方式
適用場景
1.當系統中一些對象能夠按照一致的方式去處理,例如無限極菜單\無限極權限,需要對象與整體同時使用。
2.需要隱藏組合對象與單個對象不同時,不同的單個對象的特殊方法,也不能被訪問到的場景。
3.只需要客戶端對抽象構建編程,不需要考慮內部實現的場景。
掃描二維碼
關注我吧
IT小白架構師之路