重修设计模式-结构型-组合模式

重修设计模式-结构型-组合模式

Compose objects into tree structure to represent part-whole hierarchies.Composite lets client treat individual objects and compositions of objects uniformly.

将一组对象组织成树形结构,来表示一种"部分 - 整体"的层次结构。组合让客户端可以统一单个对象和组合对象的处理逻辑。

组合模式(Composite Pattern)也叫部分-整体模式(Part-Whole), 用来描述部分与整体的关系,主要是用于处理树形结构数据。

组合模式的三个角色

  1. 组件抽象接口(Component)

    定义一些参加组合对象的通用行为或属性。

  2. 叶子节点(Leaf)

    表示叶子节点对象,下面没有其他分支,是遍历的最小单位。

  3. 组合节点(Composite)

    表示有子节点的对象,作用是组合树枝节点和叶子节点形成一个树形结构。

举个例子,在程序中表示下图的公司组织架构,并可计算总薪资情况:

其中员工是叶子节点;部门是组合节点,包含子部门和员工,是一种嵌套结构,可以表示成树这种数据结构。计算每个部门的薪资开支这样一个需求,也可以通过在树上的遍历算法来实现。用组合模式实现如下:

kotlin 复制代码
//组件抽象接口
abstract class CompanyInfo(val name: String) {
    abstract fun calculateSalary(): Double
}

//组合节点
class Department(name: String): CompanyInfo(name) {
    private val mHumanList = mutableListOf<CompanyInfo>()
    override fun calculateSalary(): Double {
        return mHumanList.sumOf { it.calculateSalary() }  //部门薪资是所有子节点的薪资总和
    }

    fun addNode(info: CompanyInfo) {
    }

    fun removeNode(name: String) {
    }
}

//叶子节点
class Employee(name: String, private val salary: Double) : CompanyInfo(name) {
    override fun calculateSalary(): Double {
        return salary	//员工薪资就是自己的
    }
}

调用处:

kotlin 复制代码
fun main() {
    val root = buildCompany()  //只需处理CompanyInfo类型,不关心子类型
    val totalSalary = root.calculateSalary()
    println("${root.name}总薪资:${totalSalary}")
}

fun buildCompany(): CompanyInfo {
    val rootCompany = Department("技术有限公司")
    val department1 = Department("研发部")
    department1.addNode(Employee("老大", 2000.0))
    department1.addNode(Employee("老三", 1500.0))
    department1.addNode(Employee("老六", 1000.0))
    rootCompany.addNode(department1)
    val department2 = Department("行政部")
    department2.addNode(Employee("大美", 3000.0))
    department2.addNode(Employee("小丽", 2500.0))
    department2.addNode(Employee("小舞", 2000.0))
    val childDepartment = Department("法务部")
    childDepartment.addNode(Employee("硬币", 10000.0))
    department2.addNode(childDepartment)
    rootCompany.addNode(department2)
    return rootCompany
}

调用时可以一致地使用组合或单个对象,不需要区分叶子节点还是组合节点。并且增加新的组合对象很容易,只需要实现组件抽象接口,不需要修改原有代码,这就是组合模式的特点。

总结

组合模式的设计思路,更像对业务场景的一种数据结构和算法的抽象。其中,数据可以表示成树这种数据结构,业务需求可以通过在树上的递归遍历算法来实现。使用组合模式的前提在于,业务场景必须能够表示成树形结构。所以组合模式的应用场景也比较局限,并不是一种很常用的设计模式。

相关推荐
Doris_202311 小时前
代码格式化 使用oxfmt
设计模式·架构·前端框架
Doris_202311 小时前
说一说ESLint+Prettier生效的原理
前端·设计模式·架构
Pomelooooo13 小时前
把 git commit 这件事,彻底交给 AI ——一个工程化 /git-commit 命令的设计与落地
设计模式
invicinble14 小时前
设计模式(类的拓扑结构)(描述总纲)
设计模式·原型模式
invicinble16 小时前
设计模式(类的拓扑结构)(为什么会产生设计模式,以及什么是设计模式)
linux·服务器·设计模式
PersonalViolet18 小时前
模板方法模式实战:重构Agent工具审批,告别重复代码
设计模式·agent
老码观察19 小时前
设计模式实战解读(五):策略模式——干掉 if-else 的优雅方案
java·设计模式·策略模式
解决问题no解决代码问题19 小时前
设计模式分类介绍
java·开发语言·设计模式
烬羽20 小时前
从 Python List 到 LLM 接口:一条被忽视的 AI 入门捷径
设计模式
我爱cope20 小时前
【Agent智能体8 | 反思设计模式-大语言模型反思机制的四个演进阶段】
人工智能·设计模式·语言模型