Java 进阶编程语言爱好者JVM · Java虚拟机原理 · JVM上语言·框架· 生态系统

设计模式(九)组合模式

2021-01-08  本文已影响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)可以适用于复杂的树形结构
缺点:
对于功能差异较大的类,难以提供公共的抽象,需要通过过度一般接口实现。

上一篇 下一篇

猜你喜欢

热点阅读