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();
        }
    }

    运行结果

    结构图:
    -北京总公司
    ---总公司人力资源部
    ---总公司财务部
    ---上海华东分公司
    -----上海华东分公司人力资源部
    -----上海华东分公司人财务部
    -----南京办事处
    -------南京办事处人力资源部
    -------南京办事处人财务部
    ---吉林东北分公司
    -----吉林东北分公司人力资源部
    -----吉林东北分公司人财务部
    -----长春办事处
    -------长春办事处人力资源部
    -------长春办事处人财务部
    职责:
    总公司人力资源部 员工招聘培训管理
    总公司财务部 公司财务收支管理
    上海华东分公司人力资源部 员工招聘培训管理
    上海华东分公司人财务部 公司财务收支管理
    南京办事处人力资源部 员工招聘培训管理
    南京办事处人财务部 公司财务收支管理
    吉林东北分公司人力资源部 员工招聘培训管理
    吉林东北分公司人财务部 公司财务收支管理
    长春办事处人力资源部 员工招聘培训管理
    长春办事处人财务部 公司财务收支管理
  • 相关阅读:
    JDBC原理及常见错误分析
    response,session,cookie
    Activity LifeCycle (安卓应用的运行机制)
    简单的接口取数据渲染到图表
    图表里面双重下拉框进行判断
    用js方式取得接口里面json数据的key和value值
    一个div多个图表共用一个图例
    一个页面多图表展示(四个div的方式)
    vue组件之子组件和父组件
    根据判断对颜色进行改变
  • 原文地址:https://www.cnblogs.com/IdealSpring/p/11871169.html
Copyright © 2011-2022 走看看