* 24種設計模式——組合模式
將物件組合成樹形結構,以表示“部分-整體”的層次結構,使得使用者對單個物件和組合物件的使用具有一致性。
一、公司組織架構1(介面篇)
1. 公司人員介面
public interface ICorp {
//獲取自己的資訊(每個員工都有資訊,你想隱藏,門兒都沒有)
public String getInfo();
}
2. 樹葉介面
public interface ILeaf extends ICorp{
}
3. 樹枝介面(包括大老闆節點 和 經理節點 )
4. 樹葉實現類public interface IBranch extends ICorp{ //能夠增加小兵(樹葉節點)或者是經理(樹枝節點)—— 不管傳什麼都是向上造型 public void addSubordinate(ICorp corp); //我還要能夠獲得下屬的資訊 public ArrayList<ICorp> getSubordinate(); }
5. 樹枝實現類public class Leaf implements ILeaf{ //葉子叫什麼名字 private String name = ""; //葉子的職位 private String position = ""; //葉子的薪水 private int salary = 0; //通過建構函式傳遞資訊 public Leaf(String name, String position, int salary) { this.name = name; this.position = position; this.salary = salary; } //最小的小兵只能獲得自己的資訊了 public String getInfo() { String info = ""; info = "名稱:"+this.name; info = info + "\t職位:"+this.position; info = info + "\t薪水:"+this.salary; return info; } }
6. 場景類public class Branch implements IBranch{ //儲存子節點的資訊 private ArrayList subordinateList = new ArrayList(); //樹枝節點的名稱 private String name = ""; //樹枝節點的職位 private String position = ""; //樹枝節點的薪水 private int salary = 0; //通過建構函式傳遞樹枝節點的引數 public Branch(String name, String position,int salary) { this.name = name; this.position = position; this.salary = salary; } //增加一個下屬,可能 是小頭目,也可能是個小兵 public void addSubordinate(ICorp corp) { this.subordinateList.add(corp); } //我有哪些下屬 public ArrayList<ICorp> getSubordinate() { return this.subordinateList; } //得到自己的資訊 public String getInfo() { String info = ""; info = "名稱:"+this.name; info = info + "\t職位:"+this.position; info = info + "\t薪水:"+this.salary; return info; } }
public class Client {
public static void main(String[] args) {
//首先是組裝一個組織結構出來
Branch ceo = compositeCorpTree();
//首先把ceo的資訊打印出來
System.out.println(ceo.getInfo());
//然後是所有員工資訊
System.out.println(getTreeInfo(ceo));
}
public static Branch compositeCorpTree(){
//首先產生總經理CEO
Branch root = new Branch("王大麻子", "總經理", 100000);
//把三個部門經理產生出來
Branch developDep = new Branch("劉大瘸子", "研發部門經理", 10000);
Branch salesDep = new Branch("馬二柺子", "銷售部門經理", 20000);
Branch financeDep = new Branch("趙三駝子", "財務部門經理", 30000);
//再把三個小組長產生出來
Branch firstDevGroup = new Branch("楊三也斜","開發一組組長",5000);
Branch secondDevGroup = new Branch("吳大植株","開發二組組長",6000);
//把所有的小兵都產生出來
Leaf a = new Leaf("a","開發人員",2000);
Leaf b = new Leaf("b","開發人員",2000);
Leaf c = new Leaf("c","開發人員",2000);
Leaf d = new Leaf("d","開發人員",2000);
Leaf e = new Leaf("e","開發人員",2000);
Leaf f = new Leaf("f","開發人員",2000);
Leaf g = new Leaf("g","開發人員",2000);
Leaf h = new Leaf("h", "銷售人員", 5000);
Leaf i = new Leaf("i", "銷售人員", 4000);
Leaf j = new Leaf("j", "財務人員", 5000);
Leaf k = new Leaf("k", "CEO祕書", 8000);
Leaf zhengLaoLiu = new Leaf("鄭老六", "研發部副經理", 20000);
//開始組裝
//CEO下有三個部門經理和一個祕書
root.addSubordinate(developDep);
root.addSubordinate(salesDep);
root.addSubordinate(financeDep);
root.addSubordinate(k);
//研發部經理
developDep.addSubordinate(firstDevGroup);
developDep.addSubordinate(secondDevGroup);
developDep.addSubordinate(zhengLaoLiu);
//看看兩個開發小組下有什麼
firstDevGroup.addSubordinate(a);
firstDevGroup.addSubordinate(b);
firstDevGroup.addSubordinate(c);
secondDevGroup.addSubordinate(d);
secondDevGroup.addSubordinate(e);
secondDevGroup.addSubordinate(f);
//再看銷售部下的人員情況
salesDep.addSubordinate(h);
salesDep.addSubordinate(i);
//最後一個財務
financeDep.addSubordinate(j);
return root;
}
//遍歷整棵樹,只要給我根節點,我就能遍歷出所有的節點
public static String getTreeInfo(Branch root){
List<ICorp> subordinateList = root.getSubordinate();
String info = "";
for(ICorp s : subordinateList){
if(s instanceof Leaf){
info = info + s.getInfo() + "\n";
}else{ //是個小頭目
info = info + s.getInfo() + "\n" + getTreeInfo((Branch)s);
}
}
return info;
}
}
二、公司組織架構(抽象類篇)
主要是把ICorp介面修改為Corp抽象類,抽象出來很多公共地方,方便很多。
1. 抽象公司職員類
public abstract class Corp {
//公司每個人都有名稱
private String name = "";
//公司每個人都有職位
private String position = "";
//公司每個人都有薪水
private int salary = 0;
public Corp(String name, String position, int salary) {
this.name = name;
this.position = position;
this.salary = salary;
}
//獲取員工資訊
public String getInfo(){
String info = "";
info = "名稱:"+this.name;
info = info + "\t職位:"+this.position;
info = info + "\t薪水:"+this.salary;
return info;
}
}
2. 樹葉節點
public class Leaf extends Corp{
//就寫一個建構函式,這個是必須 的
public Leaf(String name, String position, int salary) {
super(name, position, salary);
}
}
3. 樹枝節點
public class Branch extends Corp{
//儲存子節點的資訊
private ArrayList subordinateList = new ArrayList();
//建構函式是必須 的
public Branch(String name, String position, int salary) {
super(name, position, salary);
}
//增加一個下屬,可能 是小頭目,也可能是個小兵
public void addSubordinate(Corp corp) {
this.subordinateList.add(corp);
}
//我有哪些下屬
public ArrayList<Corp> getSubordinate() {
return this.subordinateList;
}
}
4. 稍稍修改場景類
程式碼太長,同上例,修改其中部分方法
//遍歷整棵樹,只要給我根節點,我就能遍歷出所有的節點
public static String getTreeInfo(Branch root){
List<Corp> subordinateList = root.getSubordinate();
String info = "";
for(Corp s : subordinateList){
if(s instanceof Leaf){
info = info + s.getInfo() + "\n";
}else{ //是個小頭目
info = info + s.getInfo() + "\n" + getTreeInfo((Branch)s);
}
}
return info;
}
三、組合模式定義
Component抽象構件角色:定義參加組合物件的共有方法和屬性,可以定義一些預設的行為或屬性,比如我們例子中的getInfo就封裝到了抽象類中
Leaf葉子構件:葉子物件,其下再也沒有其它分支,也就是遍歷的最小單位。
Composite樹枝構件:樹枝物件,作用是組合樹枝節點和葉子節點形成一個樹形結構。
1. 抽象構件
public abstract class Component {
//個體和整體都具有的共享
public void doSomething(){
//編寫業務邏輯
}
}
2. 樹枝構件
public class Composite extends Component{
//構件容器
private List<Component> componentArrayList = new ArrayList<Component>();
//增加一個葉子構件或樹枝構件
public void add(Component component){
this.componentArrayList.add(component);
}
//刪除一個葉子構件或樹枝構件
public void remove(Component component){
this.componentArrayList.remove(component);
}
//獲得分支下的所有葉子構件和樹枝構件
public List<Component> getChildren(){
return this.componentArrayList;
}
}
3. 樹葉構件
public class Leaf extends Component{
/*
* 可以覆寫父類方法
* public void doSomething(){
*
* }
*/
}
4. 場景類
public class Client {
public static void main(String[] args) {
//建立一個根節點
Composite root = new Composite();
root.doSomething();
//建立一個樹枝構件
Composite branch = new Composite();
//建立一個葉子節點
Leaf leaf = new Leaf();
//建立整體
root.add(branch);
branch.add(leaf);
}
//通過遞迴遍歷樹
public static void display(Composite root){
for(Component c:root.getChildren()){ //葉子節點
if(c instanceof Leaf){
c.doSomething();
}else{ //樹枝節點
display((Composite)c);
}
}
}
}
四、組合模式的應用
1.優點:
高層模組呼叫簡單:一棵樹形機構中的所有節點都是Component,區域性和整體對呼叫者來說沒有任何區別,也就是說,高層模組不必關心自己處理的是單個物件還是整個組合結構,簡化了高層模組的程式碼。
節點自由增加:使用組合模式後,如果想增加一個樹枝節點、樹葉節點都很容易,只要找到它的父節點就成,符合開閉原則。
2. 缺點
看到在我們的場景類中定義,提到樹葉和樹枝使用時的定義了嗎?直接使用了實現類!這在面向介面程式設計上是很不恰當的,與依賴倒置原則衝突,讀者在使用時要考慮清楚,它限制了你介面的影響範圍
3. 使用用場景
1)維護和展示部分-整體關係的場景,如樹形選單、檔案和資料夾管理。
2)從一個整體中能夠獨立出部分模組或功能的場景。
4. 組合模式的注意事項
只要是樹形結構,就要考慮使用組合模式,這個一定要記住,只要是要體現區域性和整體的關係的時候,而且這種關係還可能比較深,考慮一下組合模式吧
五、組合模式的擴充套件
1. 真實的組合模式
上述Client程式沒沒有改變多少,樹的組裝是跑不了的,但樹的組裝並不是像例子中的new,而是一般先有一張資料庫的表,這張資料表定義了一個樹形結構,我們把它讀取出來,然後展現到前臺上,用for迴圈加上遞迴就可以完成這個讀取,
2. 透明的組合模式(一般用安全模式就好)我們上面的例子是安全模式,下面將下透明模式,透明模式是把用來組合使用的方法放到抽象中,比如add()、remove()以及getChildren等方法(),不管葉子物件不是樹枝物件都有相同的結構,通過判斷是getChildren的返回值確認是葉子節點 不是樹枝節點,如果處理不當會在執行期出現錯誤,所以建議用上述例子中的安全模式。
1) 抽象構件
public abstract class Component {
//個體和整體都具有的共享
public void doSomething(){
//編寫業務邏輯
}
//增加一個葉子構件或樹枝構件
public abstract void add(Component component);
//刪除一個葉子構件或樹枝構件
public abstract void remove(Component component);
//獲得分支下的所有葉子構件和樹枝構件
public abstract ArrayList<Component> getChildren();
}
2) 樹葉節點
public class Leaf extends Component{
public void add(Component component) {
//空實現,直接拋一個“不支援請求”異常
throw new UnsupportedOperationException();
}
public void remove(Component component) {
//空實現,直接拋一個“不支援請求”異常
throw new UnsupportedOperationException();
}
public ArrayList<Component> getChildren() {
//空實現,直接拋一個“不支援請求”異常
throw new UnsupportedOperationException();
}
}
3) 樹結構遍歷
public class Client {
public static void main(String[] args) {
}
//通過遞迴遍歷樹
public static void display(Component root){
for(Component c:root.getChildren()){
if(c instanceof Leaf){
c.doSomething();
}else{ //樹枝節點
display(c);
}
}
}
}
3. 組合模式的遍歷(獲取父節點)
上面例子是從上向下獲取子節點,如果我想獲取父節點,可以這樣做
1)抽象構件
public abstract class Corp {
//公司每個人都有名稱
private String name = "";
//公司每個人都有職位
private String position = "";
//公司每個人都有薪水
private int salary = 0;
//父節點是誰
private Corp parent = null;
public Corp(String name, String position, int salary) {
this.name = name;
this.position = position;
this.salary = salary;
}
//獲取員工資訊
public String getInfo(){
String info = "";
info = "名稱:"+this.name;
info = info + "\t職位:"+this.position;
info = info + "\t薪水:"+this.salary;
return info;
}
//設定父節點
protected void setParent(Corp _parent){
this.parent = _parent;
}
//得到父節點
public Corp getParent(){
return this.parent;
}
}
2)樹枝構件
public class Branch extends Corp{
//儲存子節點的資訊
private ArrayList subordinateList = new ArrayList();
//建構函式是必須 的
public Branch(String name, String position, int salary) {
super(name, position, salary);
}
//增加一個下屬,可能 是小頭目,也可能是個小兵
public void addSubordinate(Corp corp) {
corp.setParent(this); //設定父節點
this.subordinateList.add(corp);
}
//我有哪些下屬
public ArrayList<Corp> getSubordinate() {
return this.subordinateList;
}
}
六、最佳實踐
一般主頁左邊的導航選單或者有樹形結構的模組都可以考慮。
相關推薦
* 24種設計模式——組合模式
將物件組合成樹形結構,以表示“部分-整體”的層次結構,使得使用者對單個物件和組合物件的使用具有一致性。 一、公司組織架構1(介面篇) 1. 公司人員介面 public interface ICorp { //獲取自己的資訊(每個員工都有資訊,你想隱藏,門兒都沒有)
Java中的24種設計模式與7大原則
工廠模式 職責 需要 占位符 ati gre template 層次 cto 一、創建型模式 1、抽象工廠模式(Abstract factory pattern): 提供一個接口, 用於創建相關或依賴對象的家族, 而不需要指定具體類.2、生成器模式(Builder pat
OOP 思想 和 設計原則 及24種設計模式
父類 分組 策略 結構 並且 實例 適配器模式 closed 不同的 oop思想:封裝、繼承、多態 把組件實現和接口分開,並且讓組件具有多態性 面向對象編程是一種解決軟件復用的設計和編程方法,這種方法把軟件中相近相似的操作邏輯和操作應用數據
Python七大原則,24種設計模式
虛擬 esp 成對 adapt 責任 低耦合 命令模式 兼容 facade 七大設計原則: 1、單一職責原則【SINGLE RESPONSIBILITY PRINCIPLE】:一個類負責一項職責. 2、裏氏替換原則【LISKOV SUBSTITUTION PRINCIPLE
(轉載)24種設計模式--原型模式【Prototype Pattern】
dex clone() new t 分享圖片 object try arr 建立 不同 今天我們來講原型模式,這個模式的簡單程度是僅次於單例模式和叠代器模式,非常簡單,但是要使用好這個模式還有很多註意事項。我們通過一個例子來解釋一下什麽是原型模式。 現在電子賬單越來越流
設計模式大雜燴(24種設計模式的總結以及學習設計模式的幾點建議)
作者:zuoxiaolong8810(左瀟龍),轉載請註明出處,特別說明:本博文來自博主原部落格,為保證新部落格中博文的完整性,特複製到此留存,如需轉載請註明新部落格地址即可。 迄今為止
24種設計模式與6大原則
外部與一個子系統的通訊必須通過一個統一的門面(Facade)物件進行,這就是門面模式。 醫院的例子 用一個例子進行說明,如果把醫院作為一個子系統,按照部門職能,這個系統可以劃分為掛號、門診、劃價、化驗、收費、取藥等。看病的病人要與這些部門打交道,就如同一個子系統的客戶端與一個子系統的各個類打交道一
* 24種設計模式——享元模式
核心:使用共享物件可有效地支援大量的細粒度的物件。運用共享技術,使得一些細粒度的物件可以共享。 一、報名系統crash多臺機器 報考系統crash,原因是使用了工廠模式來獲取物件,在大訪問量100萬時,就會有100萬個物件,因為JVM回收不及時,導致記憶體OutOfMemo
24種設計模式大全-牛人詳解
Adapter模式和Bridge模式具有一些共同的特徵。它們都給另一物件提供了一定程度上的間接性,因而有利於系統的靈活性。它們都涉及到從自身以外的一個介面向這個物件轉發請求。這些模式的不同之處主要在於它們各自的用途。Bridge模式主要是為了解決兩個已有介面之間不匹配的問題。它不考慮這些介面是怎樣實現的,也不
24種設計模式-抽象工廠模式(6)
好了,我們繼續上一節課,上一節講到女媧造人,人是造出來了,世界時熱鬧了,可是低頭一看,都是清一色的型別,缺少關愛、仇恨、喜怒哀樂等情緒,人類的生命太平淡了,女媧一想,猛然一拍腦袋,Shit!忘記給人類定義性別了,那怎麼辦?抹掉重來,然後就把人類重新洗牌,準備重新開始製造人類。
Python中的七大設計原則 + 24種設計模式
七大設計原則: 1、單一職責原則【SINGLE RESPONSIBILITY PRINCIPLE】:一個類負責一項職責. 2、里氏替換原則【LISKOV SUBSTITUTION PRINCIPLE】:繼承與派生的規則.(子類可替換父類) 3、依賴倒轉原則【D
24種設計模式複習總結
Factory Pattern(工廠模式):1. 建立物件的介面,封裝物件的建立;2. 使具體化類的工作延遲到子類中。(維護一類物件) AbstractFactory Pattern(抽象工廠 模型):該模式將一組物件的建立封裝到一個用於建立物件的類中。(解決的問題:要建
24種設計模式及案例
建立型模式 結構型模式 介面卡模式 介紹 裝飾器模式 介紹 代理模式 介紹 外觀模式 介紹 橋接模式 介紹 組合模式 介紹 享元模式 介紹 行為型模式 策略模式 介紹 模板模式 介紹 觀察者模式
JAVA的23種設計模式---組合模式
概要: 該文章參考了《設計模式之禪》一書及一些前輩的部落格文章 1.該文章闡述了組合模式的基礎原理及示例程式碼; 2.該文章適合初學設計模式的技術人員研習; 3.該文章有許多不足之處,請各位大咖指正,噴子繞道; 正文: 組合模式(合成模式、部分-整體
24種設計模式優缺點及適用場景#工廠方法模式
產品 抽象 彌補 用戶 裏氏替換原則 一個 延伸 無需 可擴展 創建型#工廠方法模式 概述: 工廠方法是簡單工廠模式的延伸,它繼承了簡單工廠模式的優點,同時還彌補了簡答工廠模式的不足。工廠方法是最常用的設計模式之一,很多開源框架和API類庫的核心模式。 優點:
24種設計模式優缺點及適用場景#抽象工廠模式
隔離 並且 strong 穩定 改變 優點 功能 方式 ron 創建型#抽象工廠模式 概述: 抽象工廠方法是工廠方法模式的延伸,它提供了功能更為強大的工廠類並且具備較好的可擴展性; 優點: 1、抽象工廠模式隔離了具體類的生成,使得客戶端並不需要知道什麽被創建
設計模式-組合模式
設計模式 組合模式 abstract class Component { protected string name; public Component(string _name) { name = _name;
重走Java設計模式——組合模式(Composite Pattern)
組合模式 定義 組合模式(Composite Pattern),又叫部分整體模式,是用於把一組相似的物件當作一個單一的物件。組合模式依據樹形結構來組合物件,用來表示部分以及整體層次。這種型別的設計模式屬於結構型模式,它建立了物件組的樹形結構。 這種模式建立了一個包含自己物
設計模式 --- 組合模式
1.定義 將物件組合成樹形結構以表示“部分-整體”的層次結構,使得使用者對單個物件和組合物件的使用具有一致性。 2.使用場景 表示物件的整體-部分層次結構時 從一個整體能夠獨立出部分模組或功能的場景 3.簡單實現 以作業系統的檔案系統為例。
設計模式-組合模式(Composite)
組合模式是構造型模式的一種。通過遞迴手段來構造樹形的物件結構,並可以通過一個物件來訪問整個物件樹 角色和職責: 就是資料夾那種形式,樹形 UML圖: 具體程式碼: import java.util.List