当前位置: 首页 > article >正文

设计模式Python版 组合模式

文章目录

  • 前言
  • 一、组合模式
  • 二、组合模式实现方式
  • 三、组合模式示例
  • 四、组合模式在Django中的应用


前言

GOF设计模式分三大类:

  • 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。
  • 结构型模式:关注类和对象之间的组合,包括适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式和代理模式。
  • 行为型模式:关注对象之间的交互,包括职责链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。

一、组合模式

组合模式(Composite Pattern)

  • 定义:组合多个对象形成树形结构以表示具有“部分—整体”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,又可以称为“部分—整体”(Part-Whole)模式。

  • 解决问题:如何使用面向对象的方式来处理软件系统中的树形结构?

  • 使用场景:

    • 在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致性地对待它们。
    • 在一个使用面向对象语言开发的系统中需要处理一个树形结构。
    • 在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,将来需要增加一些新的类型。
    • 在XML解析、组织结构树处理、文件系统设计等领域,组合模式都得到了广泛应用。
  • 组成:

    • 抽象构件(Component):它是所有容器类和叶子类的公共父类,为叶子构件和容器构件对象声明接口。一般将抽象构件类设计为接口或抽象类,将所有子类共有方法的声明和实现放在抽象构件类中。对于客户端而言,将针对抽象构件编程,而无须关心其具体子类是容器构件还是叶子构件。
    • 叶子构件(Leaf):代表组合结构中的叶节点对象,叶节点对象不再包含子节点。
    • 容器构件(Composite):它在组合模式结构中表示容器节点对象。容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点。用列表实现容器构件
  • 补充说明

    • 组合模式的关键是定义了一个抽象构件类,它既可以代表叶子,又可以代表容器。客户端针对该抽象构件类进行编程,无须知道它到底表示的是叶子还是容器,可以对其进行统一处理。
    • 容器对象与抽象构件类之间还建立一个聚合关联关系,在容器对象中既可以包含叶子,也可以包含容器,以此实现递归组合,形成一个树形结构。
  • 优点:

    • 组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次。客户端无须关心节点的层次结构,可以对所选节点进行统一处理,提高系统的灵活性。
    • 将容器对象和叶子对象进行递归组合,实现简单,灵活性好,使用频率较高。
    • 在组合模式中增加新的容器构件和叶子构件都很方便,无须对现有类库进行任何修改,符合开闭原则。
    • 组合模式为树形结构的面向对象实现提供了一种灵活的解决方案。
  • 缺点:

    • 在增加新构件时很难对容器中的构件类型进行限制。

二、组合模式实现方式

实现方式一:透明组合模式

  • 根据抽象构件类的定义形式,可将组合模式分为透明组合模式和安全组合模式两种形式。
  • 抽象构件Component中声明了所有用于管理成员对象的方法,包括add()、remove()以及getChild()等方法
  • 透明组合模式结构图

在这里插入图片描述

实现方式二:安全组合模式

  • 抽象构件Component中没有声明任何用于管理成员对象的方法,而是在Composite类中声明并实现这些方法。
  • 安全组合模式结构图

在这里插入图片描述

三、组合模式示例

使用透明组合模式来进行杀毒软件的框架设计

  • AbstractFile充当抽象构件类,Folder充当容器构件类,ImageFile、TextFile和VideoFile充当叶子构件类
"""抽象构件"""


class AbstracFile:
    def add(self, file):
        raise NotImplementedError

    def remove(self, file):
        raise NotImplementedError

    def kill_virus(self):
        raise NotImplementedError


"""容器构件"""


class Folder(AbstracFile):
    def __init__(self, name):
        self.name = name
        self.file_list: list[AbstracFile] = []

    def add(self, file):
        self.file_list.append(file)

    def remove(self, file):
        if file in self.file_list:
            self.file_list.remove(file)

    def kill_virus(self):
        # 模拟杀毒
        print(f"——对文件夹 {self.name} 进行杀毒")
        # 循环调用成员构件的业务方法
        for i in self.file_list:
            i.kill_virus()


"""叶子构件"""


class ImageFile(AbstracFile):
    def __init__(self, name):
        self.name = name

    def kill_virus(self):
        # 模拟杀毒
        print(f"——对图像文件 {self.name} 进行杀毒")


class TextFile(AbstracFile):
    def __init__(self, name):
        self.name = name

    def kill_virus(self):
        # 模拟杀毒
        print(f"——对文本文件 {self.name} 进行杀毒")


class VideoFile(AbstracFile):
    def __init__(self, name):
        self.name = name

    def kill_virus(self):
        # 模拟杀毒
        print(f"——对视频文件 {self.name} 进行杀毒")

客户端代码

# 针对抽象构件编程
folder1 = Folder("张三的资料")
folder2 = Folder("图像文件")
folder3 = Folder("文本文件")
folder4 = Folder("视频文件")

file1 = ImageFile("《洛神赋图》.gif")
file2 = ImageFile("《清明上河图》.jpg")
file3 = TextFile("《分析与设计》.txt")
file4 = TextFile("《设计模式》.doc")
file5 = VideoFile("《西游记》.rmvb")

folder2.add(file1)
folder2.add(file2)
folder3.add(file3)
folder3.add(file4)
folder4.add(file5)
folder1.add(folder2)
folder1.add(folder3)
folder1.add(folder4)

folder1.kill_virus()
# 也可以创建图形化界面让用户选择所需操作的根节点,无须修改源代码,符合开闭原则。
# folder2.kill_virus()

输出结果

——对文件夹 张三的资料 进行杀毒
——对文件夹 图像文件 进行杀毒
——对图像文件 《洛神赋图》.gif 进行杀毒   
——对图像文件 《清明上河图》.jpg 进行杀毒 
——对文件夹 文本文件 进行杀毒
——对文本文件 《分析与设计》.txt 进行杀毒 
——对文本文件 《设计模式》.doc 进行杀毒   
——对文件夹 视频文件 进行杀毒
——对视频文件 《西游记》.rmvb 进行杀毒  

四、组合模式在Django中的应用

Django 的 admin 界面允许用户以树形结构来组织模型。例如,一个 Group 可以包含多个 User,而 User 又可以属于多个 Group。在 admin 界面中,这种关系可以用组合模式来实现,其中 Group 可以看作是组合对象,而 User 可以看作是叶节点。

在这里插入图片描述


您正在阅读的是《设计模式Python版》专栏!关注不迷路~


http://www.kler.cn/a/528934.html

相关文章:

  • 【etcd】二进制安装etcd
  • 【贪心算法篇】:“贪心”之旅--算法练习题中的智慧与策略(一)
  • 全程Kali linux---CTFshow misc入门(25-37)
  • el-table组件样式如何二次修改?
  • 计算机毕业设计Python+CNN卷积神经网络考研院校推荐系统 考研分数线预测 考研推荐系统 考研爬虫 考研大数据 Hadoop 大数据毕设 机器学习
  • 深入理解MySQL 的 索引
  • DRM系列六:Drm之KMS
  • 线程的状态转换和调度
  • 深入理解Spring框架:从基础到实践
  • python学opencv|读取图像(五十三)原理探索:使用cv.matchTemplate()函数实现最佳图像匹配
  • 996引擎 -地图-添加安全区
  • 群速度与相速度辨析
  • NIST的 临床质量指标的简介
  • arkui-x 页面封装为自定义组件,巧用controller
  • Spring的AOP思想中事物管理注意点
  • 基础数据类型之整形
  • (leetcode 213 打家劫舍ii)
  • Games104——游戏引擎Gameplay玩法系统:基础AI
  • 从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架(动态菜单组件实现)
  • Dijkstra算法解析
  • 读书笔记-《Redis设计与实现》(一)数据结构与对象(下)
  • 课题介绍:水下惯性/地形组合导航精度提升的理论与方法研究
  • oracle: 多表查询之联合查询[交集intersect, 并集union,差集minus]
  • 环形缓冲区原理与C语言实现ringbuffer
  • 计算满足特定条件的素数在全体素数中的密度极限值,并将该极限值乘以10^7后向下取整的解题思路
  • Python3 【装饰器】项目实战:5个新颖的学习案例