当前位置:首页>文章>设计模式>组合模式详解 | Python代码示例与应用场景

组合模式详解 | Python代码示例与应用场景

组合模式详解

1️⃣ 概念

定义: 将对象组合成树形结构以表示"部分-整体"的层次结构;组合模式使客户端对单个对象和组合对象保持一致的方式处理。

类型: 结构性

2️⃣ 适用场景

  • 希望客户端可以忽略组合对象与单个对象的差异时
  • 处理一个树形结构时

3️⃣ 优点

  • 清楚的定义分层次的复杂对象,表示对象的全部或部分层次
  • 让客户端忽略了层次的差异,方便对整个层次结构进行控制
  • 简化客户端代码
  • 符合开闭原则

4️⃣ 缺点

  • 限制类型时会比较复杂
  • 使设计变的更加抽象

5️⃣ 组合模式Coding

① 创建CatalogComponent类

from abc import ABC, abstractmethod
from typing import List

class CatalogComponent(ABC):
    def add(self, catalog_component):
        raise NotImplementedError("不支持添加操作")

    def remove(self, catalog_component):
        raise NotImplementedError("不支持删除操作")

    def get_name(self):
        raise NotImplementedError("不支持获取名称操作")

    def get_price(self):
        raise NotImplementedError("不支持获取价格操作")

    def print(self):
        raise NotImplementedError("不支持打印操作")

② 创建Course类继承CatalogComponent类

class Course(CatalogComponent):
    def __init__(self, name: str, price: float):
        self.name = name
        self.price = price

    def get_name(self):
        return self.name

    def get_price(self):
        return self.price

    def print(self):
        print(f"Course Name:{self.name} Price:{self.price}")

③ 创建CourseCatalog类继承CatalogComponent类

class CourseCatalog(CatalogComponent):
    def __init__(self, name: str, level: int):
        self.items: List[CatalogComponent] = []
        self.name = name
        self.level = level

    def add(self, catalog_component: CatalogComponent):
        self.items.append(catalog_component)

    def get_name(self):
        return self.name

    def remove(self, catalog_component: CatalogComponent):
        if catalog_component in self.items:
            self.items.remove(catalog_component)

    def print(self):
        print(self.name)
        for catalog_component in self.items:
            if self.level is not None:
                for i in range(self.level):
                    print("  ", end="")
            catalog_component.print()

④ 编写测试代码

def main():
    linux_course = Course("Linux课程", 11)
    windows_course = Course("Windows课程", 11)

    python_course_catalog = CourseCatalog("Python课程目录", 2)

    mmall_course1 = Course("Python电商一期", 55)
    mmall_course2 = Course("Python电商二期", 66)
    design_pattern = Course("Python设计模式", 77)

    python_course_catalog.add(mmall_course1)
    python_course_catalog.add(mmall_course2)
    python_course_catalog.add(design_pattern)

    imooc_main_course_catalog = CourseCatalog("课程主目录", 1)
    imooc_main_course_catalog.add(linux_course)
    imooc_main_course_catalog.add(windows_course)
    imooc_main_course_catalog.add(python_course_catalog)

    imooc_main_course_catalog.print()

if __name__ == "__main__":
    main()

运行结果:

课程主目录
  Linux课程 Price:11
  Windows课程 Price:11
  Python课程目录
    Python电商一期 Price:55
    Python电商二期 Price:66
    Python设计模式 Price:77

6️⃣ 组合模式的实际应用

Python GUI框架 tkinter

tkinter中的Widget类就是一个很好的组合模式例子,Container类可以包含其他Widget,而Leaf Widget(如Button、Label)则是叶子节点。

import tkinter as tk

# 示例:Frame可以包含其他组件,体现了组合模式
root = tk.Tk()
frame = tk.Frame(root)  # 组合对象
button = tk.Button(frame, text="Click")  # 叶子对象
label = tk.Label(frame, text="Hello")    # 叶子对象

Python collections.abc

Python的collections.abc模块中的Container、Iterable等抽象基类也体现了组合模式的思想。

Django模型继承

Django的模型继承和组合也是组合模式的实际应用:

from django.db import models

class Component(models.Model):
    name = models.CharField(max_length=100)

    class Meta:
        abstract = True

class Leaf(Component):
    value = models.CharField(max_length=100)

class Composite(Component):
    children = models.ManyToManyField('self', blank=True)
设计模式

享元模式详解:Python实现与应用场景全面解析

2025-9-8 9:58:56

设计模式

桥接模式详解 | Python桥接模式示例与应用解析

2025-9-10 11:08:15

搜索