设计模式-组合模式

来源:互联网 发布:麦迪62分数据 编辑:程序博客网 时间:2024/06/05 18:21

定义:

(GoF《设计模式》):将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

概述:

组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。

有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。

组合模式让你可以优化处理递归或分级数据结构。有许多关于分级数据结构的例子,使得组合模式非常有用武之地。关于分级数据结构的一个普遍性的例子是你每次使用电脑时所遇到的:文件系统。文件系统由目录和文件组成。每个目录都可以装内容。目录的内容可以是文件,也可以是目录。按照这种方式,计算机的文件系统就是以递归结构来组织的。如果你想要描述这样的数据结构,那么你可以使用组合模式Composite。

组合模式可以让客户端像修改配置文件一样简单的完成本来需要流程控制语句来完成的功能。

模式中的角色:

1.Component 是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。

2.Leaf 在组合中表示叶子结点对象,叶子结点没有子结点。

3.Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。

角色关系UML:

这里写图片描述

使用场景:

以下情况下适用Composite模式:
1.你想表示对象的部分-整体层次结构
2.你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

经典案例:系统目录结构,网站导航结构等。

总结:

组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以像处理简单元素一样来处理复杂元素。如果你想要创建层次结构,并可以在其中以相同的方式对待所有元素,那么组合模式就是最理想的选择。


公司包含部门和子公司,子公司又可以包含部门和子公司为例

UML图如下:

这里写图片描述

Java代码:

接口:

package demo18;/** *  * @ClassName: CompanyOrDept * @Description:公司和部门抽象 * @author cheng * @date 2017-8-22 上午09:41:27 */public interface CompanyOrDept {    /**     *      * @Title: getName     * @Description:获取公司或部门名称     */    String getName();    /**     *      * @Title: add     * @Description: 添加公司或部门     * @param companyOrDept     */    void add(CompanyOrDept companyOrDept);    /**     *      * @Title: remove     * @Description: 删除公司或部门     * @param companyOrDept     */    void remove(CompanyOrDept companyOrDept);    /**     *      * @Title: display     * @Description: 展示公司或部门     * @param i i仅仅表示展示的时候,前面加几个"-",并没有什么实际含义     */    void display(int i);    /**     *      * @Title: lineOfDuty     * @Description:展示部门职能     */    void lineOfDuty();}

叶子节点:

package demo18;/** *  * @ClassName: FinanceDept * @Description:财务 * @author cheng * @date 2017-8-22 上午10:07:17 */public class FinanceDept implements CompanyOrDept {    private String deptName;    /**     *      * @param deptName     */    public FinanceDept(String deptName) {        this.deptName = deptName;    }    @Override    public String getName() {        return this.deptName;    }    @Override    public void display(int i) {        StringBuffer sb = new StringBuffer();        for (int j = 0; j < i; j++) {            sb.append("-");        }        System.out.println(sb.toString() + this.getName());    }    @Override    public void lineOfDuty() {        // TODO Auto-generated method stub        System.out.println(this.getName() + "   公司财务收支管理");    }    @Override    public void add(CompanyOrDept companyOrDept) {        // TODO Auto-generated method stub    }    @Override    public void remove(CompanyOrDept companyOrDept) {        // TODO Auto-generated method stub    }}
package demo18;/** *  * @ClassName: HRDept * @Description:HR * @author cheng * @date 2017-8-22 上午10:07:17 */public class HRDept implements CompanyOrDept {    private String deptName;    /**     *      * @param deptName     */    public HRDept(String deptName) {        this.deptName = deptName;    }    @Override    public String getName() {        return this.deptName;    }    @Override    public void display(int i) {        StringBuffer sb = new StringBuffer();        for (int j = 0; j < i; j++) {            sb.append("-");        }        System.out.println(sb.toString() + this.getName());    }    @Override    public void lineOfDuty() {        // TODO Auto-generated method stub        System.out.println(this.getName() + "   公司人力资源管理");    }    @Override    public void add(CompanyOrDept companyOrDept) {        // TODO Auto-generated method stub    }    @Override    public void remove(CompanyOrDept companyOrDept) {        // TODO Auto-generated method stub    }}

非叶子节点:

package demo18;import java.util.ArrayList;import java.util.List;/** *  * @ClassName: Company * @Description: 公司 * @author chengrui * @date 2017-8-22 上午09:55:45 */public class Company implements CompanyOrDept {    // 公司或部门抽象    private List<CompanyOrDept> children = new ArrayList<CompanyOrDept>();    // 公司名称    private String companyName;    /**     *      * @param companyName     */    public Company(String companyName) {        this.companyName = companyName;    }    @Override    public void add(CompanyOrDept companyOrDept) {        children.add(companyOrDept);    }    @Override    public void remove(CompanyOrDept companyOrDept) {        children.remove(companyOrDept);    }    @Override    public void display(int i) {        StringBuffer sb = new StringBuffer();        for (int j = 0; j < i; j++) {                                                                 sb.append("-");        }        System.out.println(sb.toString() + this.getName());        for (CompanyOrDept companyOrDept : children) {            companyOrDept.display(i + 2);        }    }    @Override    public void lineOfDuty() {        for (CompanyOrDept companyOrDept : children) {            companyOrDept.lineOfDuty();        }    }    @Override    public String getName() {        return this.companyName;    }}

测试:

package demo18;/** *  * @ClassName: ClientTest * @Description:测试 * @author cheng * @date 2017-8-22 上午10:13:07 */public class ClientTest {    public static void main(String[] args) {        // 总公司        CompanyOrDept headCompany = new Company("总公司");        headCompany.add(new FinanceDept("总公司财务管理"));        headCompany.add(new HRDept("总公司人力资源"));        // 北京分公司        CompanyOrDept BJCompany = new Company("北京分公司");        BJCompany.add(new FinanceDept("北京分公司财务管理"));        BJCompany.add(new HRDept("北京分公司人力资源"));        // 上海分公司        CompanyOrDept SHCompany = new Company("上海分公司");        SHCompany.add(new FinanceDept("上海分公司财务管理"));        SHCompany.add(new HRDept("上海分公司人力资源"));        // 添加分公司到总公司        headCompany.add(BJCompany);        headCompany.add(SHCompany);        System.out.println("===========公司结构=============");        headCompany.display(1);        System.out.println("===========部门职能=============");        headCompany.lineOfDuty();        // 移除上海分公司        headCompany.remove(SHCompany);        System.out.println("===========公司结构=============");        headCompany.display(1);        System.out.println("===========部门职能=============");        headCompany.lineOfDuty();    }}

运行结果:
这里写图片描述

原创粉丝点击