1.定义
是一种将对象组合成树状的层次结构的模式,用来表示“部分-整体”的关系,使用户对单个对象和组合对象具有一致的访问性。
2.场景
需求:展示公司所有部门的员工
2.1 重构前
public class Company {
private List<Department> departmentList = new ArrayList<>();
private String name;
public Company(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void addDepartment(Department department) {
departmentList.add(department);
}
public void display() {
System.out.println("company:" + name);
for(Department department : departmentList){
department.display();
}
}
}
public class Department {
private List<Staff> staffList = new ArrayList<>();
private String name;
public Department(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void addStaff(Staff staff) {
staffList.add(staff);
}
public void display() {
System.out.println("department:" + name);
for (Staff staff : staffList) {
staff.display();
}
}
}
public class Staff {
private List<Staff> staffList = new ArrayList<>();
private String name;
public Staff(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void display() {
System.out.println("staff:" + name);
}
}
// 第一版
Company company = new Company("小型公司");
Department department1 = new Department("财务部");
Department department2 = new Department("技术部");
Department department3 = new Department("人事部");
company.addDepartment(department1);
company.addDepartment(department2);
company.addDepartment(department3);
Staff staff1 = new Staff("张三");
Staff staff2 = new Staff("李四");
Staff staff3 = new Staff("王五");
Staff staff4 = new Staff("赵六");
Staff staff5 = new Staff("孙七");
department1.addStaff(staff1);
department2.addStaff(staff2);
department2.addStaff(staff3);
department3.addStaff(staff4);
department3.addStaff(staff5);
company.display();
----------------------------console
company:小型公司
department:财务部
staff:张三
department:技术部
staff:李四
staff:王五
department:人事部
staff:赵六
staff:孙七
问题:由于部门扩展,技术部要增加两个新的子部门:风控部,数据部该怎么办呢?
由于公司,部门和员工存在明显的“整体-部分”的特点,可以使用组合模式改造代码。
2.2 重构后
公司,部门和员工的抽象接口,定义了几种添加和展示方法
public interface Organization {
void addCompany(Organization organization);
void addDepartment(Organization organization);
void addStaff(Organization organization);
void display();
}
重新设计这些类,对不能使用的方式抛出UnsupportedOperationException,防止被误调用。
public class Company implements Organization {
private List<Organization> organizationList = new ArrayList<>();
private String name;
public Company(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void addCompany(Organization organization) {
organizationList.add(organization);
}
@Override
public void addDepartment(Organization organization) {
organizationList.add(organization);
}
@Override
public void addStaff(Organization organization) {
throw new UnsupportedOperationException(); // 不能直接添加员工
}
@Override
public void display() {
System.out.println("company:" + name);
for (Organization organization : organizationList) {
organization.display();
}
}
}
public class Department implements Organization {
private List<Organization> organizationList = new ArrayList<>();
private String name;
public Department(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void addCompany(Organization organization) {
throw new UnsupportedOperationException();
}
@Override
public void addDepartment(Organization organization) {
organizationList.add(organization);
}
@Override
public void addStaff(Organization organization) {
organizationList.add(organization);
}
public void display() {
System.out.println("department:" + name);
for (Organization organization : organizationList) {
organization.display();
}
}
}
public class Staff implements Organization{
private String name;
public Staff(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void addCompany(Organization organization) {
throw new UnsupportedOperationException();
}
@Override
public void addDepartment(Organization organization) {
throw new UnsupportedOperationException();
}
@Override
public void addStaff(Organization organization) {
throw new UnsupportedOperationException();
}
public void display() {
System.out.println("staff:" + name);
}
}
// 测试代码
Company company = new Company("小型公司");
Department department1 = new Department("财务部");
Department department2 = new Department("技术部");
Department department3 = new Department("人事部");
company.addDepartment(department1);
company.addDepartment(department2);
company.addDepartment(department3);
Staff staff1 = new Staff("张三");
Staff staff2 = new Staff("李四");
Staff staff3 = new Staff("王五");
Staff staff4 = new Staff("赵六");
Staff staff5 = new Staff("孙七");
department1.addStaff(staff1);
department2.addStaff(staff2);
department2.addStaff(staff3);
department3.addStaff(staff4);
department3.addStaff(staff5);
// company.display();
Department department4 = new Department("风控部");
Department department5 = new Department("数据部");
department2.addDepartment(department4);
department2.addDepartment(department5);
Staff staff6 = new Staff("小李");
Staff staff7 = new Staff("小芬");
department4.addStaff(staff6);
department5.addStaff(staff7);
company.display();