博主介绍: ✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家✌
Java知识图谱点击链接:体系化学习Java(Java面试专题)
💕💕 感兴趣的同学可以收藏关注下 ,不然下次找不到哟💕💕
1、什么是组合模式
组合模式是一种结构型设计模式,它允许你将对象组合成树形结构来表现“部分-整体”的层次关系。组合模式使得用户对单个对象和组合对象的使用具有一致性,可以用来处理树形结构数据的递归遍历和操作。组合模式将对象组织成树形结构,其中每个节点都可以是单个对象或其他组合对象,这样就可以创建出复杂的层次结构。组合模式包含三个角色:抽象构件(Component)、叶子构件(Leaf)和容器构件(Composite)。其中抽象构件是组合中的抽象类或接口,叶子构件是组合中的叶子节点,容器构件是组合中的容器节点,用于包含其他节点。
2、组合模式的优缺点
组合模式的优点:
- 简化客户端代码:组合模式可以让客户端代码更简单,因为客户端不需要知道处理的是单个对象还是组合对象,可以统一使用相同的方式来处理它们。
增加新的构件更方便:使用组合模式可以很方便地增加新的构件,只需要实现抽象构件接口即可,不需要修改现有的代码。
灵活性好:组合模式可以让你灵活地组合对象,可以随意添加、删除或替换构件,而不会影响整个系统的稳定性。
易于扩展:组合模式可以很容易地扩展,可以在不修改现有代码的情况下增加新的行为。
组合模式的缺点:
可能会导致设计过度复杂:如果组合模式的层次结构过于复杂,可能会导致设计过度复杂,使得代码难以理解和维护。
可能会降低系统性能:由于组合模式需要递归遍历整个树形结构,可能会降低系统的性能。如果组合模式的层次结构过于复杂,可能会导致性能下降更为明显。
可能会增加系统的抽象性:组合模式需要使用抽象类或接口来定义抽象构件,可能会增加系统的抽象性,降低代码的可读性和可维护性。
3、组合模式的应用场景
组合模式的应用场景包括:
树形结构:组合模式最常见的应用场景是树形结构,例如文件系统、菜单、部门组织结构等。
GUI控件:GUI控件通常也是树形结构,例如窗口、面板、按钮、文本框等。
组织架构:组合模式可以用于描述组织架构,例如公司的部门、岗位、员工等。
图形图像处理:图形图像处理中的复杂图形通常也是由简单的图形组合而成的,例如图形编辑器中的图形对象等。
任务调度:任务调度系统中的任务通常也是树形结构,例如任务调度器中的任务、子任务等。
数据库操作:数据库操作中的查询语句也可以使用组合模式来描述,例如SQL语句中的SELECT语句等。
数学公式:数学公式中的复杂式子通常也是由简单的式子组合而成的,例如微积分中的复合函数等。
4、组合模式的结构
组合模式的结构包含以下几个角色:
抽象构件(Component):是组合中所有对象的抽象基类,定义了对象的基本行为和属性,可以包含一些默认实现或者抛出异常等。
叶子构件(Leaf):是组合中的叶子节点对象,它没有子节点,实现了抽象构件的所有方法。
容器构件(Composite):是组合中的容器节点对象,它包含了叶子节点或容器节点,实现了抽象构件的所有方法,同时也包含了一些管理子节点的方法,例如添加、删除、获取子节点等。
客户端(Client):通过抽象构件接口操作组合中的对象,可以是叶子节点或容器节点,不需要知道具体的对象类型。
5、组合模式的代码案例
以下是一个简单的组合模式代码案例,以公司组织架构为例:
package com.pany.camp.design.principle.organization;
import java.util.List;
/**
*
* @description: 抽象类
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: pany
* @version: 1.0.0
* @createTime: 2023-06-27 22:19
*/
public abstract class Employee {
private String name;
private String position;
public Employee(String name, String position) {
this.name = name;
this.position = position;
}
public String getName() {
return name;
}
public String getPosition() {
return position;
}
public abstract void add(Employee employee);
public abstract void remove(Employee employee);
public abstract List<Employee> getSubordinates();
}
package com.pany.camp.design.principle.organization;
import java.util.ArrayList;
import java.util.List;
/**
* @description: 叶子构件
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: pany
* @version: 1.0.0
* @createTime: 2023-06-27 22:20
*/
public class Developer extends Employee {
public Developer(String name, String position) {
super(name, position);
}
public void add(Employee employee) {
// 叶子节点无法添加子节点,抛出异常或者不做任何操作
}
public void remove(Employee employee) {
// 叶子节点无法删除子节点,抛出异常或者不做任何操作
}
public List<Employee> getSubordinates() {
// 叶子节点无法获取子节点,返回空列表
return new ArrayList<>();
}
}
package com.pany.camp.design.principle.organization;
import java.util.ArrayList;
import java.util.List;
/**
*
* @description: 容器构件
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: pany
* @version: 1.0.0
* @createTime: 2023-06-27 22:21
*/
public class Manager extends Employee {
private List<Employee> subordinates;
public Manager(String name, String position) {
super(name, position);
subordinates = new ArrayList<>();
}
public void add(Employee employee) {
subordinates.add(employee);
}
public void remove(Employee employee) {
subordinates.remove(employee);
}
public List<Employee> getSubordinates() {
return subordinates;
}
}
package com.pany.camp.design.principle.organization;
/**
*
* @description: 客户端
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: pany
* @version: 1.0.0
* @createTime: 2023-06-27 22:25
*/
public class Client {
public static void main(String[] args) {
Employee CEO = new Manager("John", "CEO");
Employee CTO = new Manager("Jack", "CTO");
Employee CFO = new Manager("Tom", "CFO");
Employee developer1 = new Developer("Mike", "Developer");
Employee developer2 = new Developer("David", "Developer");
Employee developer3 = new Developer("Eric", "Developer");
CTO.add(developer1);
CTO.add(developer2);
CFO.add(developer3);
CEO.add(CTO);
CEO.add(CFO);
// 遍历整个组织架构
System.out.println(CEO.getName() + " (" + CEO.getPosition() + ")");
for (Employee manager : CEO.getSubordinates()) {
System.out.println("- " + manager.getName() + " (" + manager.getPosition() + ")");
for (Employee developer : manager.getSubordinates()) {
System.out.println("-- " + developer.getName() + " (" + developer.getPosition() + ")");
}
}
}
}
抽象构件为 Employee ,包含了添加、删除、获取子节点等方法,叶子构件为 Developer ,无法添加子节点,容器构件为 Manager ,可以添加、删除子节点。客户端通过抽象构件接口操作组合中的对象,遍历整个公司组织架构。
输出结果如下:
John (CEO)
- Jack (CTO)
-- Mike (Developer)
-- David (Developer)
- Tom (CFO)
-- Eric (Developer)
Process finished with exit code 0
💕💕 本文由激流原创,首发于CSDN博客,博客主页 https://blog.csdn.net/qq_37967783?spm=1010.2135.3001.5421
💕💕喜欢的话记得点赞收藏啊