python 设计模式之组合模式Composite Pattern

 #引入一

文件夹对咱们来讲很熟悉,文件夹里面能够包含文件夹,也能够包含文件。html

那么文件夹是个容器,文件夹里面的文件夹也是个容器,文件夹里面的文件是对象。python

 

 这是一个树形结构编程

我们生活工做中经常使用的一种结构设计模式

文件是一个简单对象,我直接打开就可使用。文件夹是复杂对象,由于里面还有子文件夹 或者是文件。安全

 我在用这个文件夹的时候,我用相同的方式对待文件夹和文件。架构

其实这时候咱们就是在使用设计模式中的组合模式了了app

 

#引入二

这是从人家的博客上截的图spa

公司的组织架构也是经常使用的树形结构,也适合使用组合模式设计

 

 

#组合模式定义

 组合模式(Composite Pattern),又叫部分总体模式,是用于把一组类似的对象看成一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及总体层次。这种类型的设计模式属于结构型模式,它建立了对象组的树形结构。3d

这种模式建立了一个包含本身对象组的类。该类提供了修改相同对象组的方式。

 

 #使用场景

一、想表示对象的部分-总体层次结构(树形结构)。

二、但愿用户忽略组合对象与单个对象的不一样,用户将统一地使用组合结构中

3‘若是你想要建立层次结构,并能够在其中以相同的方式对待全部元素,那么组合模式就是最理想的选择

 

#涉及角色

百度百科粘过来的

1.Component 是组合中的对象声明接口,在适当的状况下,实现全部类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。
2.Leaf 在组合中表示叶子结点对象,叶子结点没有子结点。

3.Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操做,如增长(add)和删除(remove)等

 

 

 

#组合模式的优势

 组合模式的主要优势以下:

      (1) 组合模式能够清楚地定义分层次的复杂对象,表示对象的所有或部分层次,它让客户端忽略了层次的差别,方便对整个层次结构进行控制。

      (2) 客户端能够一致地使用一个组合结构或其中单个对象,没必要关心处理的是单个对象仍是整个组合结构,简化了客户端代码。

      (3) 在组合模式中增长新的容器构件和叶子构件都很方便,无须对现有类库进行任何修改,符合“开闭原则”。

      (4) 组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,经过叶子对象和容器对象的递归组合,能够造成复杂的树形结构,但对树形结构的控制却很是简单。

 

#组合模式的缺点

 组合模式的主要缺点以下:

      在增长新构件时很难对容器中的构件类型进行限制。有时候咱们但愿一个容器中只能有某些特定类型的对象,例如在某个文件夹中只能包含文本文件,使用组合模式时,不能依赖类型系统来施加这些约束,由于它们都来自于相同的抽象层,在这种状况下,必须经过在运行时进行类型检查来实现,这个实现过程较为复杂。

 

#组合模式有两种

(1) 透明组合模式

      透明组合模式中,抽象构件Component中声明了全部用于管理成员对象的方法,包括add()、remove()以及getChild()等方法,这样作的好处是确保全部的构件类都有相同的接口。在客户端看来,叶子对象与容器对象所提供的方法是一致的,客户端能够相同地对待全部的对象。透明组合模式也是组合模式的标准形式。

      透明组合模式的缺点是不够安全,由于叶子对象和容器对象在本质上是有区别的。叶子对象不可能有下一个层次的对象,即不可能包含成员对象,所以为其提供add()、remove()以及getChild()等方法是没有意义的,这在编译阶段不会出错,但在运行阶段若是调用这些方法可能会出错(若是没有提供相应的错误处理代码)。

 (2) 安全组合模式

  安全组合模式中,在抽象构件Component中没有声明任何用于管理成员对象的方法,而是在Composite类中声明并实现这些方法。这种作法是安全的,由于根本不向叶子对象提供这些管理成员对象的方法,对于叶子对象,客户端不可能调用到这些方法。

安全组合模式的缺点是不够透明,由于叶子构件和容器构件具备不一样的方法,且容器构件中那些用于管理成员对象的方法没有在抽象构件类中定义,所以客户端不能彻底针对抽象编程,必须有区别地对待叶子构件和容器构件。在实际应用中,安全组合模式的使用频率也很是高,在Java AWT中使用的组合模式就是安全组合模式。

 

  #举个栗子 (python实现组合模式)

#抽象一个组织类
class Component:
    def __init__(self,name):
        self.name=name

    def add(self,comp):
        pass
    def remove(slef,comp):
        pass
    def display(self,depth):
        pass

#叶子节点
class Leaf(Component):
    def add(self):
        print('不能添加子节点')
    def remove(self):
        print('不能删除子节点')
    def display(self,depth):
        strtemp=''
        for i in range(depth):
            strtemp +='---'
        print(strtemp+self.name)

#枝节点
class Composite(Component):
    def __init__(self,name):
        self.name=name
        self.children=[]
    def add(self,comp):
        self.children.append(comp)
    def remove(self,comp):
        self.children.remove(comp)
    def display(self,depth):
        strtemp=''
        for i in range(depth):
            strtemp += '---'
        print(strtemp+self.name)
        for comp in self.children:
            comp.display(depth+2)

if __name__=='__main__':
    root=Composite('根')
    
    root.add(Leaf('叶1a'))
    root.add(Leaf('叶1b'))
    root.add(Leaf('花1a'))
    root.add(Leaf('花1b'))
    comp1a=Composite('枝1a')
    comp1b=Composite('枝1b')
    root.add(comp1a)
    root.add(comp1b)

    comp1a.add(Leaf('叶2a'))
    comp1a.add(Leaf('叶2b'))
    comp1a.add(Leaf('花2a'))
    comp1a.add(Leaf('花2b'))
    comp2a=Composite('枝2a')
    comp1a.add(comp2a)

    comp1b.add(Leaf('叶2a'))
    comp1b.add(Leaf('花2a'))

    comp2a.add(Leaf('叶3a'))
    comp2a.add(Leaf('花3a'))
    comp3a=Composite('枝3a')
    comp2a.add(comp3a)

    comp3a.add(Leaf('叶4a'))
    comp3a.add(Leaf('花4a')) 
    
    root.display(1)
    

 

 

 

参考

https://www.cnblogs.com/fxycm/p/4887680.html

https://baike.baidu.com/item/%E7%BB%84%E5%90%88%E6%A8%A1%E5%BC%8F/1441281

https://www.cnblogs.com/lfxiao/p/6816026.html

https://www.runoob.com/design-pattern/composite-pattern.html

https://www.jianshu.com/p/68ada9b3cff9

还有参考其余连接,忘记贴地址了

相关文章
相关标签/搜索