iOS组合模式

539 阅读2分钟

简介:

组合模式描述了一组对象,它们的处理方式与相同类型对象的单个实例相同。组合的目的是将对象“组合”成树结构以表示部分-整体层次结构,实现让客户统一对待单个对象和组合。

概述:

组合设计模式可以解决什么问题?

  • 应该表示部分-整体层次结构,以便客户端可以统一处理部分和整体对象
  • 部分-整体层次结构应表示为树结构。

复合设计模式描述了什么解决方案?

  • 为部分Leaf对象和整体Composite对象定义统一的 Component 接口
  • 单个 Leaf 对象直接实现 Component 接口,Composite 对象将请求转发给它们的子组件

这使客户端能够通过 Component 接口统一处理 LeafComposite 对象,Leaf 对象直接执行请求,Composite 对象将请求向下递归转发到它们的子组件。这使得客户端类更易于实现、更改、测试和重用。

UML 与类图:

在上面的 UML 类图中,Client 类没有直接(分别)引用 LeafComposite 类。相反,Client 引用公共 Component 接口,可以统一对待 LeafComposite

Leaf 类没有子类,直接实现了 Component 接口。

Composite 类维护一个子组件对象(子组件)的容器,并将请求转发给这些子组件(对于子组件中的每个子组件:child.operation())。

图中角色作用:

Component:

  • 是所有组件的抽象,包括复合组件
  • 声明组合中对象的接口

Leaf:

  • 表示组合中的叶对象
  • 实现所有组件方法

Composite:

  • 表示一个复合组件(有子组件的组件)
  • 实现操作children的方法
  • 实现所有的 Component 方法,通常是通过将它们委托给children

例子:

下面的例子是用 Swift 编写的,它实现了一个图形类,它可以是一个椭圆,也可以是几个图形的组合。每个图形都可以打印。

  /** "Component" */
  protocol Graphic {
      func print();
  }
  ​
  /** "Composite" */
  struct CompositeGraphic:Graphic {
      private var childGraphics:Array<Graphic>? = []
      
      public mutating func add(graphic:Graphic){
          childGraphics?.append(graphic)
      }
      
      public mutating func add(compositGraphic:CompositeGraphic){
          childGraphics?.append(compositGraphic)
      }
      
      func print() {
          for graphic in childGraphics! {
              graphic.print()
          }
      }
      
  }
  ​
  /** "Leaf" */
  struct Ellipse:Graphic {
      func print() {
          Swift.print("Ellipse")
      }
  }
  ​
  /** Client */
  struct CompositeDemo {
      func main()  {
          //Initialize four ellipses
          let ellipse1 = Ellipse()
          let ellipse2 = Ellipse()
          let ellipse3 = Ellipse()
          let ellipse4 = Ellipse()
          
          //Creates two composites containing the ellipses
          var compositGraphic2 = CompositeGraphic()
          compositGraphic2.add(graphic: ellipse1)
          compositGraphic2.add(graphic: ellipse2)
          compositGraphic2.add(graphic: ellipse3)
  ​
          var compositGraphic3 = CompositeGraphic()
          compositGraphic3.add(graphic: ellipse4)
          
          var compositGraphic = CompositeGraphic()
          compositGraphic.add(compositGraphic: compositGraphic2)
          compositGraphic.add(compositGraphic: compositGraphic3)
  ​
          //Prints the complete graphic (Four times the string "Ellipse").
          compositGraphic.print();
  ​
          
      }
  }