11.2 透明的组合模式

    在上述结构中,我们对于子节点的管理操作(add、remove和getChild等)放在了分支类(BranchComposite)里,叶子类(BranchLeaf)看不到这些操作的定义。我们还有一种方式,把管理子节点的操作放在Component,然后让叶子类的这些操作在运行时失效(可以不做任何处理,也可以抛出异常等),这样对客户对象来说,这种方式更加透明。

    我们把前者称为安全的组合模式,因为叶子节点没有add、remove和getChild这样的操作,如果尝试调用这些方法,在编译时就会报错;而后者在运行过程中才可能被发现,但是这种方式具有良好的透明性,我们称之为透明的组合模式。

    透明的组合模式对叶子节点调用add等操作的处理有两种方式。

    运行时报错,例如抛出一个异常等。

    忽略这些无意义的操作,不做任何逻辑处理,对于没有自动内存回收机制的语言来说,使用这种方式要特别注意垃圾回收。

    我们现在就为上述场景重构透明的组合模式,首先我们需要把以前子类(BranchComposite)的add、remove和getChild操作上移至父类(BranchComponent)。为了让叶子节点的这些操作失效,我们有两种选择。

    父类Component中声明这些方法为abstract,然后分别在Composite子类和leaf子类中实现这些操作,但是Leaf类在这些操作中只能实现失效的逻辑。

    父类中就实现这些失效的操作,那么只在Composite子类中覆写这些操作。

    我们这里选用第2种方式,使用BranchComponent类的add、remove和getChild操作会抛出异常,这样前述的BranchComposite类和BranchLeaf类的代码则不需要发生任何改变。UML静态类图如图11-4所示。

    figure_0175_0186

    图11-4

    BranchComponent类的代码大致如下。

    figure_0175_0187

    figure_0176_0188

    测试代码和执行非常简单,这里就不再赘述,请参见之前的示例代码。