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