导言

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

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

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

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

Python设计模式(6):组合模式_数据

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

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

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

组合模式的优点如下。

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

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()

今天的文章有不懂的可以加群,群号:822163725,备注:小陈学Python,不备注可是会被拒绝的哦~!

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

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


Python设计模式(6):组合模式_层次结构_04