zoukankan      html  css  js  c++  java
  • 浅谈Java设计模式——组合模式(Composite)

    一、概述

            将对象组合成树形结构以表示"部分-整体"的层次结构。"Composite使得用户对单个对象和组合对象的使用具有一致性。它定义了如何将容器对象和叶子对象进行递归组合,使得客户在使用的过程中无须进行区分,可以对他们进行一致的处理。在使用组合模式中需要注意一点也是组合模式最关键的地方:叶子对象和组合对象实现相同的接口。这就是组合模式能够将叶子节点和对象节点进行一致处理的原因。虽然组合模式能够清晰地定义分层次的复杂对象,也使得增加新构件也更容易,但是这样就导致了系统的设计变得更加抽象,如果系统的业务规则比较复杂的话,使用组合模式就有一定的挑战了。

    二、使用场景

    1.你想表示对象的部分-整体层次结构。

    2.你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

    三、参与者

    1.Component 为组合中的对象声明接口。 在适当的情况下,实现所有类共有接口的缺省行为。 声明一个接口用于访问和管理Component                         的子组件。 (可选)在递归结构中定义一个接口,用于访问一个父部件,并在合适的情况下实现它。

    2.Leaf 在组合中表示叶节点对象,叶节点没有子节点。 在组合中定义节点对象的行为。 

    3.Composite 定义有子部件的那些部件的行为。 存储子部件。 在Component接口中实现与子部件有关的操作。 

    4.Client 通过Component接口操纵组合部件的对象。

    四、类图

    五、代码示例

    1.Component

    /**
     * Component
     * @author zhipeng_Tong
     */
    public abstract class Company {
        protected String name;
    
        public Company(String name) {
            this.name = name;
        }
    
        public abstract void add(Company company);  // 添加
        public abstract void remove(Company company);   // 删除
        public abstract void display(int depth);    // 显示
        public abstract void lineOfDuty();  // 履行职责
    }

    2.Leaf

    /**
     * Leaf
     * @author zhipeng_Tong
     */
    public class FinanceDepartment extends Company {
        public FinanceDepartment(String name) {
            super(name);
        }
    
        @Override
        public void add(Company company) {
    
        }
    
        @Override
        public void remove(Company company) {
    
        }
    
        @Override
        public void display(int depth) {
            for (int i = 0; i < depth; i++)
                System.out.print("-");
            System.out.println(name);
        }
    
        @Override
        public void lineOfDuty() {
            System.out.println(String.format("%s 公司财务收支管理", name));
        }
    }

    /**
     * Leap
     * @author zhipeng_Tong
     */
    public class HRDepartment extends Company {
        public HRDepartment(String name) {
            super(name);
        }
    
        @Override
        public void add(Company company) {
    
        }
    
        @Override
        public void remove(Company company) {
    
        }
    
        @Override
        public void display(int depth) {
            for (int i = 0; i < depth; i++)
                System.out.print("-");
            System.out.println(name);
        }
    
        @Override
        public void lineOfDuty() {
            System.out.println(String.format("%s 员工招聘培训管理", name));
        }
    }

    3.Composite

    /**
     * Composite
     * @author zhipeng_Tong
     */
    public class ConcreteCompany extends Company{
        private ArrayList<Company> companies = new ArrayList<>();
    
        public ConcreteCompany(String name) {
            super(name);
        }
    
        @Override
        public void add(Company company) {
            companies.add(company);
        }
    
        @Override
        public void remove(Company company) {
            companies.remove(companies);
        }
    
        @Override
        public void display(int depth) {
            toDisplay(depth);
    
            for (Company c : companies)
                c.display(depth + 2);
        }
    
        private void toDisplay(int depth) {
            for (int i = 0; i < depth; i++)
                System.out.print("-");
            System.out.println(name);
        }
    
        @Override
        public void lineOfDuty() {
            for (Company c : companies)
                c.lineOfDuty();
        }
    }

    4.Client 通过Component接口操纵组合部件的对象。

    public class Client {
        public static void main(String[] args) {
            ConcreteCompany root = new ConcreteCompany("北京总公司");
            root.add(new HRDepartment("总公司人力资源部"));
            root.add(new FinanceDepartment("总公司财务部"));
    
            ConcreteCompany company = new ConcreteCompany("上海华东分公司");
            company.add(new HRDepartment("上海华东分公司人力资源部"));
            company.add(new FinanceDepartment("上海华东分公司人财务部"));
            root.add(company);
    
            ConcreteCompany company2 = new ConcreteCompany("南京办事处");
            company2.add(new HRDepartment("南京办事处人力资源部"));
            company2.add(new FinanceDepartment("南京办事处人财务部"));
            company.add(company2);
    
            ConcreteCompany company3 = new ConcreteCompany("吉林东北分公司");
            company3.add(new HRDepartment("吉林东北分公司人力资源部"));
            company3.add(new FinanceDepartment("吉林东北分公司人财务部"));
            root.add(company3);
    
            ConcreteCompany company4 = new ConcreteCompany("长春办事处");
            company4.add(new HRDepartment("长春办事处人力资源部"));
            company4.add(new FinanceDepartment("长春办事处人财务部"));
            company3.add(company4);
    
            System.out.println("结构图:");
            root.display(1);
    
            System.out.println("职责:");
            root.lineOfDuty();
        }
    }

    运行结果

    结构图:
    -北京总公司
    ---总公司人力资源部
    ---总公司财务部
    ---上海华东分公司
    -----上海华东分公司人力资源部
    -----上海华东分公司人财务部
    -----南京办事处
    -------南京办事处人力资源部
    -------南京办事处人财务部
    ---吉林东北分公司
    -----吉林东北分公司人力资源部
    -----吉林东北分公司人财务部
    -----长春办事处
    -------长春办事处人力资源部
    -------长春办事处人财务部
    职责:
    总公司人力资源部 员工招聘培训管理
    总公司财务部 公司财务收支管理
    上海华东分公司人力资源部 员工招聘培训管理
    上海华东分公司人财务部 公司财务收支管理
    南京办事处人力资源部 员工招聘培训管理
    南京办事处人财务部 公司财务收支管理
    吉林东北分公司人力资源部 员工招聘培训管理
    吉林东北分公司人财务部 公司财务收支管理
    长春办事处人力资源部 员工招聘培训管理
    长春办事处人财务部 公司财务收支管理
  • 相关阅读:
    Mysql 服务无法启动 服务没有报告任何错误
    mysql国内镜像下载网址
    windows上自动设置java环境变量的脚本
    史上最详细的新浪广告系统技术架构优化历程
    十分钟理解广告系统
    Nginx基础配置指令
    nginx配置详情(总结)
    利用tcpdump抓包工具监控TCP连接的三次握手和断开连接的四次挥手
    Windows7配置QT-Android开发环境!
    一位计算机专业硕士毕业生的求职经历和感想[转载]
  • 原文地址:https://www.cnblogs.com/IdealSpring/p/11871169.html
Copyright © 2011-2022 走看看