大话设计模式—组合模式
組合模式(Composite Pattern),又叫部分整體模式,是用于把一組相似的對象當作一個單一的對象。組合模式依據樹形結構來組合對象,用來表示部分以及整體層次。這種類型的設計模式屬于結構型模式,它創建了對象組的樹形結構。這種模式創建了一個包含自己對象組的類。該類提供了修改相同對象組的方式。
大話設計模式中程杰老師給出的定義是,組合模式:將對象組合成樹形結構以表示”部分-整體”的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。
組合模式結構圖:
首先,讓我們通過過一個簡單的實例來簡單了解一下組合模式做基本的用法。實例演示了一個組織中員工的層次結構。
創建Employee類:
package com.exercise.composite;import java.util.ArrayList; import java.util.List;public class Employee {private String name;private String dept;private int salary;private List<Employee> subordinates;//部下//constructorpublic Employee(String name, String dept, int salary,List<Employee> subordinates) {super();this.name = name;this.dept = dept;this.salary = salary;this.subordinates = subordinates;subordinates = new ArrayList<Employee>();}public Employee(String name, String dept, int salary) {super();this.name = name;this.dept = dept;this.salary = salary;subordinates = new ArrayList<Employee>();}public void add(Employee e){subordinates.add(e);}public void remove(Employee e){subordinates.remove(e);}public List<Employee> getSubordinates(){return subordinates;}public String toString(){return "Employee :[ Name : " + name + ", dept : " + dept + ", salary :"+ salary + " ]";} }測試類:
package com.exercise.composite; /*** 使用Employee來創建和打印員工的層次結構* @author lmb**/ public class CompositePatternDemo {public static void main(String[] args) {Employee CEO = new Employee("John","CEO", 30000);Employee headSales = new Employee("Robert","Head Sales", 20000);Employee headMarketing = new Employee("Michel","Head Marketing", 20000);Employee clerk1 = new Employee("Laura","Marketing", 10000);Employee clerk2 = new Employee("Bob","Marketing", 10000);Employee salesExecutive1 = new Employee("Richard","Sales", 10000);Employee salesExecutive2 = new Employee("Rob","Sales", 10000);CEO.add(headSales);CEO.add(headMarketing);headSales.add(salesExecutive1);headSales.add(salesExecutive2);headMarketing.add(clerk1);headMarketing.add(clerk2);//打印該組織的所有員工System.out.println("-------------------公司員工情況----------------------");System.out.println(CEO);for (Employee headEmployee : CEO.getSubordinates()) {//打印CEO的直屬一級部下System.out.println(headEmployee);for (Employee employee : headEmployee.getSubordinates()) {//打印CEO的二級部下System.out.println(employee);}} }}運行結果:
使用場景:
需求中是體現部分與整體層次結構的時候,以及當我們希望用戶可以忽略組合對象與單個對象的不同,統一的使用組合結構中的所有對象時。簡而言之,就是涉及到部分、整體場景時,如樹形菜單,文件、文件夾的管理。
主要解決:它在我們樹型結構的問題中,模糊了簡單元素和復雜元素的概念,客戶程序可以向處理簡單元素一樣來處理復雜元素,從而使得客戶程序與復雜元素的內部結構解耦。
如何解決:樹枝和葉子實現統一接口,樹枝內部組合該接口。
一般在工作中說起部分和總體我們想到最多的大概就是總公司和分公司了,如果我們需要做一套辦公管理系統,并且總公司的人力資源部、財務部等的辦公掛歷功能在所有的分公司也都要有,我們該怎么實現?
功能實現:
抽象公司類或接口
package com.composite;public abstract class Company {protected String name;public Company(String name){this.name = name;}public abstract void add(Company company);//addpublic abstract void remove(Company company);//removepublic abstract void display(int depth);//displaypublic abstract void lineofDuty();//line of duty}具體公司類(樹枝節點)
package com.composite;import java.util.ArrayList; import java.util.List;public class ConcreteCompany extends Company {private List<Company> childrenCompany = new ArrayList<Company>();public ConcreteCompany(String name) {super(name);}@Overridepublic void add(Company company) {childrenCompany.add(company);}@Overridepublic void display(int depth) {System.out.println("第 " + depth + " 層的機構名為: " + name);for (Company c : childrenCompany) {c.display(depth + 1);}}@Overridepublic void lineofDuty() {for (Company c : childrenCompany) {c.lineofDuty();}}@Overridepublic void remove(Company company) {childrenCompany.remove(company);}}財務部和人力資源部(樹葉節點)
package com.composite;public class HRDepartment extends Company {public HRDepartment(String name) {super(name);}@Overridepublic void add(Company company) {}@Overridepublic void display(int depth) {System.out.println("第 " + depth + " 層的機構名為: " + name);}@Overridepublic void lineofDuty() {System.out.println(name + " 負責員工招聘管理培訓");}@Overridepublic void remove(Company company) {}} package com.composite;public class FinanceDepartment extends Company {public FinanceDepartment(String name) {super(name);}@Overridepublic void add(Company company) {}@Overridepublic void display(int depth) {System.out.println("第 " + depth + " 層的機構名為: " + name);}@Overridepublic void lineofDuty() {System.out.println(name + " 負責公司財務收支管理");}@Overridepublic void remove(Company company) {}}測試方法
package com.composite;public class CompositePatternDemo {public static void main(String[] args) {//一個總公司ConcreteCompany root = new ConcreteCompany("北京總公司");root.add(new HRDepartment("總公司人力資源部"));root.add(new FinanceDepartment("總公司財務部"));//三個子公司ConcreteCompany com1 = new ConcreteCompany("廣州分公司");com1.add(new HRDepartment("廣州分公司人力資源部"));com1.add(new FinanceDepartment("廣州分公司財務部"));root.add(com1);ConcreteCompany com2 = new ConcreteCompany("杭州分公司");com2.add(new HRDepartment("杭州分公司人力資源部"));com2.add(new FinanceDepartment("杭州分公司財務部"));root.add(com2);ConcreteCompany com3 = new ConcreteCompany("深圳分公司");com3.add(new HRDepartment("深圳分公司人力資源部"));com3.add(new FinanceDepartment("深圳分公司財務部"));root.add(com3);System.out.println("-------公司結構圖--------");root.display(1);System.out.println("----------各部門職責----------");root.lineofDuty();}}運行結果:
這樣,通過組合模式我們就定義了包含人力資源部和財務部這些基本對象和分公司等組合對象的類層次結構。
基本對象可以被組合成更復雜的組合對象,而這個組合對象又可以被組合,這樣不斷的遞歸下去,在客戶代碼中,任何用到基本對象的地方都可以使用組合對象了。組合模式讓客戶可以一致的使用組合結構和單個對象。
應用實例:
1、算術表達式包括操作數、操作符和另一個操作數,其中,另一個操作符也可以是操作樹、操作符和另一個操作數。
2、在 JAVA AWT 和 SWING 中,對于 Button 和 Checkbox 是樹葉,Container 是樹枝。
優點:
1、高層模塊調用簡單。
2、節點自由增加。
缺點:
在使用組合模式時,其葉子和樹枝的聲明都是實現類,而不是接口,違反了依賴倒置原則。
總結
以上是生活随笔為你收集整理的大话设计模式—组合模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大话设计模式—备忘录模式
- 下一篇: 大话设计模式—桥接模式