前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python设计模式(6):组合模式

Python设计模式(6):组合模式

作者头像
不可言诉的深渊
发布2019-07-26 17:25:48
1.3K0
发布2019-07-26 17:25:48
举报

导言

在软件设计与编程中经常会遇到树形数据。当处理树形结构的数据时,程序员必须经常区分叶子节点与树的一个树枝节点。这往往会使代码变得更加复杂,并且很容易出错。组合模式即为解决这个问题的一个有效解决办法,即允许一致对待复杂和原始对象的接口。在面向对象编程技术中,组合对象是一个或者多个相似对象构成的对象,各个对象有相似的功能。关键的概念是客户类以相同的方式对待单独的对象与一组对象,即所谓的组合对象。

组合模式有时候又叫部分 - 整体模式。在树型结构问题中模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。

组合模式指将对象组合成树形结构,以表示“部分 - 整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

组合模式结构图如图所示。

组合模式所包含的各组成部分意义如下。

  1. Component:为组合模式中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为,声明一个接口用于访问和管理其子组件;在递归结构中定义一个接口,用于访问一个父组件,并在合适的情况下实现。
  2. Leaf:在组合模式中表示叶节点对象,叶节点对象没有子节点,实现 Component 的所有方法。
  3. Composite:表示组合部件(注意部件带有子部件),实现操纵子部件的所有方法;实现所有在 Component 的操作。
  4. Client:通过 Component 接口操纵组合部件的对象。

各组成部分的协作过程是,用户使用 Component 类接口与组合结构中的对象进行交互。如果接受者是一个 Leaf,则直接处理请求;如果接受者是 Composite,则通常将请求发送给其子部件,在转发请求之前或之后可能执行一些辅助操作。

组合模式的优点如下。

  1. 定义了包含基本对象和组合对象的类层次结构,基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合。
  2. 简化了客户代码。客户可以一致的使用组合对象和单个对象,通常用户不知道处理的是一个叶节点还是一个组合组件。
  3. 使得更容易增加新类型的组件。新定义的 Composite 和 Leaf 子类自动与已有的结构和客户代码一起工作,客户程序不需要因为新的 Component 类而去改变。
  4. 使设计变得更通用。
代码语言:javascript
复制
from abc import ABC, abstractmethod


class Component(ABC):
    def __init__(self, name):
        self.name = name

    @abstractmethod
    def operation(self, depth):
        pass

    @abstractmethod
    def add(self, c):
        pass

    @abstractmethod
    def remove(self, c):
        pass

    @abstractmethod
    def get_child(self, index):
        pass


class Composite(Component):
    def __init__(self, name):
        Component.__init__(self, name)
        self.children = []

    def operation(self, depth):
        strtemp = ''
        for i in range(depth):
            strtemp += strtemp+'-'
        print(strtemp+self.name)
        for comp in self.children:
            comp.operation(depth+2)

    def add(self, c):
        self.children.append(c)

    def remove(self, c):
        self.children.remove(c)

    def get_child(self, index):
        return self.children[index]


class Leaf(Component):
    def operation(self, depth):
        strtemp = ''
        for i in range(depth):
            strtemp += strtemp+'-'
        print(strtemp+self.name)

    def add(self, c):
        print('不能添加下级节点!')

    def remove(self, c):
        print('不能删除下级节点!')

    def get_child(self, index):
        print('没有下级节点!')


class Client:
    @staticmethod
    def main():
        # 生成树根
        root = Composite("root")
        # 根上长出2个叶子
        root.add(Leaf('leaf A'))
        root.add(Leaf('leaf B'))
        # 根上长出树枝Composite X
        comp = Composite("Composite X")
        comp.add(Leaf('leaf XA'))
        comp.add(Leaf('leaf XB'))
        root.add(comp)
        # 根上长出树枝Composite X
        comp2 = Composite("Composite XY")
        # Composite X长出2个叶子
        comp2.add(Leaf('leaf XYA'))
        comp2.add(Leaf('leaf XYB'))
        root.add(comp2)
        # 根上又长出2个叶子,C和D,D没长好,掉了
        root.add(Leaf('Leaf C'))
        leaf = Leaf("Leaf D")
        root.add(leaf)
        root.remove(leaf)
        # 展示组织
        root.operation(1)


if __name__ == '__main__':
    Client.main()
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python机器学习算法说书人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档