设计模式(九)组合模式

作者: 我犟不过你 | 来源:发表于2021-01-08 14:51 被阅读0次

    1、概述

    组合模式是一种结构型设计模式, 你可以使用它将对象组合成树状结构, 并且能像使用独立对象一样使用它们。


    组合模式

    2、适用场景

    1)如果你需要实现树状对象结构, 可以使用组合模式。
    2)如果你希望客户端代码以相同方式处理简单和复杂元素, 可以使用该模式。

    3、实例

    有以下场景:

    有一个公司,内部有很多员工employee。
    分为CEO,manager,staff
    

    创建顶层抽象类:

    /**
     * 员工抽象
     * @date: 2021/1/8
     * @author weirx
     * @version 3.0
     */
    public abstract class Employee {
    
        private String name;
        private List<Employee> employee;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public List<Employee> getEmployee() {
            return employee;
        }
    
        public void setEmployee(List<Employee> employee) {
            this.employee = employee;
        }
    
        public Employee(String name, List<Employee> employee) {
            this.name = name;
            this.employee = employee;
        }
    }
    

    创建公司:

    /**
     * 公司
     * @date: 2021/1/8
     * @author weirx
     * @version 3.0
     */
    public class Company extends Employee {
    
    
        public Company(String name, List<Employee> employee) {
            super(name, employee);
        }
    
        public void desc() {
            System.out.println("this is company,name is " + super.getName());
            List<Employee> list = this.getEmployee();
            System.out.println("---------------------");
            list.forEach(c -> {
                System.out.println("I am CEO ,my name is " + c.getName());
                c.getEmployee().forEach(m -> {
                    System.out.println("I am manager ,my name is " + m.getName()+ ";my leader is " + c.getName());
                    m.getEmployee().forEach(s -> {
                        System.out.println("I am staff ,my name is " + s.getName()+ ";my leader is " + m.getName());
                    });
                });
            });
    
        }
    }
    

    创建CEO:

    /**
     * CEO
     * @date: 2021/1/8
     * @author weirx
     * @version 3.0
     */
    public class CEO extends Employee {
    
        public CEO(String name, List<Employee> employee) {
            super(name, employee);
        }
    
        public void desc(){
            System.out.println("I am CEO,my name is " + super.getName()+",employee is "+ super.getEmployee());
        }
    }
    

    创建经理:

    /**
     * 经理
     * @date: 2021/1/8
     * @author weirx
     * @version 3.0
     */
    public class Manager extends Employee{
    
        public Manager(String name, List<Employee> employee) {
            super(name, employee);
        }
    
        public void desc(){
            System.out.println("I am manager,my name is " + super.getName()+",employee is "+ super.getEmployee());
        }
    }
    

    创建员工:

    /**
     * 员工
     * @date: 2021/1/8
     * @author weirx
     * @version 3.0
     */
    public class Staff extends Employee {
    
        public Staff(String name, List<Employee> employee) {
            super(name, employee);
        }
    
        public void desc() {
            System.out.println("I am staff,my name is " + super.getName() + ",employee is " + super.getEmployee());
        }
    }
    

    测试类:

    /**
     * 客户端
     * @date: 2021/1/4
     * @author weirx
     * @version 3.0
     */
    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = BsspUserApplication.class)
    public class TestDemo {
    
        @Test
        public void test() {
    
            //创建一个公司
            Company company = new Company("神奇公司",new ArrayList<>());
            //招聘公司的CEO
            CEO ceo = new CEO("神奇",new ArrayList<>());
            //招聘经理
            Manager manager1 = new Manager("神奇一号",new ArrayList<>());
            Manager manager2 = new Manager("神奇二号",new ArrayList<>());
            Manager manager3 = new Manager("神奇三号",new ArrayList<>());
            //招聘员工
            Staff staff1 = new Staff("员工一号", new ArrayList<>());
            Staff staff2 = new Staff("员工二号", new ArrayList<>());
            Staff staff3 = new Staff("员工三号", new ArrayList<>());
            Staff staff4 = new Staff("员工四号", new ArrayList<>());
            Staff staff5 = new Staff("员工五号", new ArrayList<>());
            //组装公司组织结构
            //安排经理下属
            manager1.getEmployee().add(staff1);
            manager1.getEmployee().add(staff2);
            manager2.getEmployee().add(staff3);
            manager2.getEmployee().add(staff4);
            manager3.getEmployee().add(staff5);
            //安排ceo下属
            ceo.getEmployee().add(manager1);
            ceo.getEmployee().add(manager2);
            ceo.getEmployee().add(manager3);
            //安排ceo到公司
            company.getEmployee().add(ceo);
            //输出公司组织架构
            company.desc();
    
        }
    
    }
    

    结果:

    this is company,name is 神奇公司
    ---------------------
    I am CEO ,my name is 神奇
    I am manager ,my name is 神奇一号;my leader is 神奇
    I am staff ,my name is 员工一号;my leader is 神奇一号
    I am staff ,my name is 员工二号;my leader is 神奇一号
    I am manager ,my name is 神奇二号;my leader is 神奇
    I am staff ,my name is 员工三号;my leader is 神奇二号
    I am staff ,my name is 员工四号;my leader is 神奇二号
    I am manager ,my name is 神奇三号;my leader is 神奇
    I am staff ,my name is 员工五号;my leader is 神奇三号
    

    4、分析

    如上面的例子,我们将公司的员工,包括CEO,manager,staff作为叶子添加到了容器company当中,最后由客户端TestDemo进行组装,得到了公司的树形组织结构。

    从扩展层面看,比如要新增CTO,只需要增加CTO类,而无需修改其他代码,符合开闭原则。

    5、总结

    优点:
    1)符合开闭原则
    2)可以适用于复杂的树形结构
    缺点:
    对于功能差异较大的类,难以提供公共的抽象,需要通过过度一般接口实现。

    相关文章

      网友评论

        本文标题:设计模式(九)组合模式

        本文链接:https://www.haomeiwen.com/subject/pbgloktx.html