首页 > 代码库 > 7.5.1.1复合设计模式(THE COMPOSITE DESIGN PATTERN)

7.5.1.1复合设计模式(THE COMPOSITE DESIGN PATTERN)

7.5.1.1复合设计模式(THE COMPOSITE DESIGN PATTERN)

 

复合模式可以把几个对象组合成一个复合对象,使用这种的方法与使用基本对象一样。图 7.6 显示了面向对象实现这种模式的通常方法。


图 7.6CompositeComponent 是包含其他组件集合的类;它继承自 AbstractComponent,因此,能够使用基本组件的地方,也一样可以使用其他组件,比如,ConcreteComponent。

 

复合对象用复合类表示,程序能够使用 AbstractComponent 类来处理,因此,不需要知道基本对象与复合对象之间的区别。我们还可以看一个使用虚拟方法的示例,称为 Operatio;在 CompositeComponent 类中,它在 components 集合中的所有对象上迭代,并调用 Operation 方法。在我们的文档表示中,可以找到类似的情况。当使用 SplitPart,把一个部分拆分为多列或行时,我们把它当作普通文档部分看待,与处理其他部分的方式完全相同。这部分由保存在列表中的其他部分组合而成。我们可以重写图 7.6 普通示例,使用与 F# 递归差别联合类型相同的方式: 

 

type AbstractComponent 

  | CompositeComponent oflist<AbstractComponent> 

  | ConcreteComponent of (...) 

  | (...)

 

在这个示例中,复合值表示成除了其他基本组件之外的可选值,它递归地引用 AbstractComponent 类型,把这个类型的值保存在表示组合对象的列表中。当处理 AbstractComponent 类型的值时,我们不需要区别对待组合值和基本值,这正是这种设计模式的主要目标。

在函数式编程中,组合是类型的公开表现。因此,类型的任何用户都知道组件由组合创建,用在写基本的处理函数时,可以使用,正如我们在实现 mapDocument 操作时所做的。

使用函数式数据结构,重点是在已有类型上增加新函数的能力,因此,使组合公开,是正确的设计决策。这样,函数式代码也不需要定义 Operation 方法,在面向对象的表示方法中,它是 AbstractComponent 类型的一部分;使用该类型的任何操作可以独立实现,与处理函数的类型相同。

F# 有一个高级功能,称为活动模式(active patterns),在一定程度上能够封装组合。这就能够能够公开组合,而不仅是整个差别联合类型,这对开发F# 库是有用的。我们在书中不讨论此功能的细节,你可以在本书的网站上找到更多的内容。

7.5.1.1复合设计模式(THE COMPOSITE DESIGN PATTERN)