组合模式是一个很经典的模式,单看名字可能觉得很陌生,但看完它的应用场景你会觉得很熟悉,比如树形结构的多级菜单,一个节点可能是菜单也可能是菜单项。这个模式最大的好处是可以让我们以一致的方式处理个别对象以及对象组合。这里的个别对象就是菜单项,对象组合就是菜单。还有一个例子就是Linux系统,整个linux系统就是一个树形结构,在Linux里一切皆文件。
组合模式里,带子元素的元素称为节点(node),没有子元素的元素称为叶子节点(leaf)。为了保持对客户的透明性,组合内所有的对象必须要实现相同的接口,否则客户就必须要操心哪个对象用哪个接口,这样就失去了组合模式的意义。不过这时有一个问题就是叶子节点是没有孩子的,但依然可以调用它的getChildren方法,这时可以返回null或者抛出异常,看具体情况。这里可以理解为叶子节点是没有孩子的节点。所以它的getChildren方法也是有意义的。
在组合模式里,遍历是很简单的,如果想遍历所有节点的信息,只需要用递归即可。比如所有节点都有print方法,调用要节点的print方法时,如果遇到子节点是一个组合对象时,调用它的print方法时会开始另一个遍历,依次类推。