关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

深入浅出设计模式 - 组合模式

发布时间:2023-06-28 00:00:31
博主介绍: 博主从事应用安全和大数据领域,有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 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 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 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 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喜欢的话记得点赞收藏啊

/template/Home/leiyu/PC/Static