1。什么是组合模式?将对象组合成树结构以表示部分-整体层次结构。Composite允许客户端统一处理单个对象和对象的组合。CompositePattern:将对象组合成树状结构来表示部分-整体的层次结构,使得用户在使用单个对象和组合对象时具有一致性。说人话:用来处理树状结构的数据。2.组合方式定义①Component抽象组件角色定义了参与组合的对象的公共方法和属性,可以定义一些默认的行为或属性。②Leaf叶子节点叶子对象,其下没有其他子节点,是遍历的最小单位。③复合分支组件branch对象,作用是将分支节点和叶节点组合起来形成一个树结构。3.组合模式通用代码实现/***个体和整体抽象*/publicabstractclassComponent{//个体和整体共享publicvoiddoSomething(){//通用业务逻辑System.out.println("通用业务逻辑");}}/***分支节点*/publicclassCompositeextendsComponent{//组件容器privateArrayListcomponentArrayList=newArrayList<>();//添加一个叶节点或分支节点publicvoidadd(Componentcomponent){this.componentArrayList.add(component);}//删除叶子节点或分支节点publicvoidremove(Componentcomponent){this.componentArrayList.remove(component);}//获取所有的分支Leaf节点和分支节点publicListgetChildren(){returnthis.componentArrayList;}}/***叶节点*/publicclassLeafextendsComponent{//覆盖父类方法@OverridepublicvoiddoSomething(){//叶节点逻辑System.out.println("叶节点逻辑");}}Test:publicclassClientTest{publicstaticvoidmain(String[]args){//创建根节点Compositeroot=newComposite();root.doSomething();//创建分支组件Compositebranch=newComposite();//创建一个叶子节点Leafleaf=newLeaf();//串联连接root.add(branch);分支.add(叶);显示(根);}//通过递归遍历publicstaticvoiddisplay(Compositeroot){for(Componentc:root.getChildren()){if(cinstanceofLeaf){//叶子节点c.doSomething();}else{显示((复合)c);}}}}这里我们举个例子:假设我们正在开发一个OA系统(办公自动化系统)公司的组织结构包括部门和员工两类数据。其中,一个部门可以包含子部门和员工。我们希望在内存中建立一个整个公司(部门、子部门、员工隶属关系)的人员结构图,并提供一个接口来计算部门的工资成本(属于该部门的所有员工的工资总和)。/***部门类和员工类的抽像类*/publicabstractclassHumanResource{protectedlongid;受保护的双薪;publicHumanResource(longid){this.id=id;}publiclonggetId(){返回id;}publicabstractdoublecalculateSalary();}publicclassDepartmentextendsHumanResource{privateListsubNodes=newArrayList<>();公共部门(longid){super(id);}@OverridepublicdoublecalculateSalary(){doubletotalSalary=0d;for(HumanResourcehr:subNodes){totalSalary+=hr.calculateSalary();}this.salary=totalSalary;返回总工资;}publicvoidaddSubNode(HumanResourcehumanResource){subNodes.add(humanResource);}}publicclassEmployeeextendsHumanResource{publicEmployee(longid,doublesalary){super(id);this.salary=工资;}@OverridepublicdoublecalculateSalary(){返回工资;}}测试:publicclassPersonClientTest{privatestaticfinallongORGANIZATION_ROOT_ID=1;publicstaticvoidmain(String[]args){//创建总部部门root=newDepartment(ORGANIZATION_ROOT_ID);//创建子部门Departmentbranch=newDepartment(2L);//创建一个雇员Employeeemployee1=newEmployee(21L,2000);雇员employee2=newEmployee(22L,4000);root.addSubNode(分支);branch.addSubNode(employee1);branch.addSubNode(employee2);双v=root.calculateSalary();System.out.println(v);}privatevoidbuildOrganization(Departmentdepartment){//根据部门id查询数据库中所有下属部门的id//ListsubDepartmentIds=departmentRepo.getSubDepartmentIds(department.getId());ListsubDepartmentIds=newArrayList<>();for(LongsubDepartmentId:subDepartmentIds){部门subDepart换货=新部门(subDepartmentId);department.addSubNode(子部门);建立组织(子部门);}//根据部门id及其关联的所有员工id查询数据库//ListemployeeIds=employeeRepo.getDepartmentEmployeeIds(department.getId());ListemployeeIds=newArrayList<>();for(LongemployeeId:employeeIds){//根据employeeId查询数据库得到salary//假设是1000doublesalary=1000d;department.addSubNode(newEmployee(employeeId,salary));}}}4。组合模式的优点①高层模块调用简单树状结构中的所有节点都是Components,对于调用者来说没有局部和全局的区别,也就是说高层模块不需要关心它简化了无论您是处理单个对象还是整个复合结构,高级模块的代码。②节点可自由添加使用复合模式后,如果要查找其父节点,添加分支节点或叶子节点非常容易。易于扩展,符合开闭原则,对以后的维护非常有利。5.组合模式应用场景只要是树形结构,都可以考虑使用组合模式。①维护和展示部分整体关系的场景,如树形菜单、文件和文件夹管理。②部分模块或功能可以脱离整体的场景。