结构型——组合模式

发布于:2025-03-25 ⋅ 阅读:(62) ⋅ 点赞:(0)

组合模式

组合模式是一种结构型设计模式,用于将对象组合成树形结构以表示“部分-整体”的层次关系。使得客户端能够以统一的方式处理单个对象和组合对象

特点

  • 统一接口:客户端无需区分操作的是单个对象还是组合对象。
  • 递归结构:组合对象可以嵌套其他组合对象或者叶子节点,形成树形结构。
  • 透明性:所有的方法都在已抽象组件中声明
  • 动态拓展:新增组件类型时,无需修改现有代码

模式结构

角色 描述
抽象组件 (Component) 定义组合对象和叶子对象的共有接口,声明管理叶子组件的方法。
叶子 (Leaf) 定义叶子对象(无子节点)的行为,实现抽象组件所声明的接口。
组合 (Composite) 定义组合对象(包含子组件的复杂对象)的行为,实现抽象组件所声明的接口。

简单示例

from abc import ABC, abstractmethod
from typing import List

# 抽象组件
class FileSystem(ABC):
    @abstractmethod
    def display(self, indent: int=0) -> None: pass

    def add(self, Composite: 'FileSystem') -> None:
        raise NotImplementedError("叶子节点不支持添加子节点")

    def remove(self, Composite: 'FileSystem') -> None:
        raise NotImplementedError("叶子节点不支持删除子节点")

# 叶子节点
class File(FileSystem):
    def __init__(self, name: str) -> None:
        self.name = name

    def display(self, indent: int=0) -> None:
        print("|  " * indent + "|--" + self.name)

    # 叶子节点的其他方法已经在抽象组件中声明

# 组合节点
class Directory(FileSystem):
    def __init__(self, name: str) -> None:
        self.name = name
        self.children: List[FileSystem] = []

    def display(self, indent: int=0) -> None:
        print("|  " * indent + "|--" + self.name)
        for child in self.children:
            child.display(indent + 1)

    def add(self, child: FileSystem) -> None:
        self.children.append(child)
    
    def remove(self, child: FileSystem) -> None:
        self.children.remove(child)


# 客户端使用
if __name__ == "__main__":
    root = Directory("root")
    tmp = Directory("tmp")
    bin = Directory("bin")
    root.add(tmp)
    root.add(bin)

    file1 = File("file1.txt")
    file2 = File("file2.txt")
    tmp.add(file1)
    bin.add(file2)

    root.display()
    # |--root
    # |  |--tmp
    # |  |  |--file1.txt
    # |  |--bin
    # |  |  |--file2.txt

    bin.remove(file2)
    root.display()
    # |--root
    # |  |--tmp
    # |  |  |--file1.txt
    # |  |--bin

优缺点

  • 优点
    • 支持递归操作,即对树形结构可以进行统一的处理
    • 灵活拓展新组件类型
    • 简化客户端的使用,全部都是统一接口
  • 缺点
    • 透明式设计在叶子节点上可能未实现某些操作导致运行错误
    • 组合层次过深时调试困难

使用场景

  • 菜单栏(菜单项和子菜单)
  • 文件系统(文件夹和文件)
  • 组织架构(部门和员工)

网站公告

今日签到

点亮在社区的每一天
去签到