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

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

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
}

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

总结

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

相关推荐
晨米酱12 小时前
JavaScript 中"对象即函数"设计模式
前端·设计模式
数据智能老司机17 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机18 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机18 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机18 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
使一颗心免于哀伤18 小时前
《设计模式之禅》笔记摘录 - 21.状态模式
笔记·设计模式
数据智能老司机2 天前
精通 Python 设计模式——创建型设计模式
python·设计模式·架构
数据智能老司机2 天前
精通 Python 设计模式——SOLID 原则
python·设计模式·架构
烛阴2 天前
【TS 设计模式完全指南】懒加载、缓存与权限控制:代理模式在 TypeScript 中的三大妙用
javascript·设计模式·typescript
李广坤2 天前
工厂模式
设计模式