组合模式,属于结构型模式,更加关注的对象与对象的结构。
组合模式,又叫部分-整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
上面图片相信大家再熟悉不过了,二叉树,节点里面有节点,整个树即使一个整体,又可以看做是节点的部分。相似的机构还有好多,比如:总公司和分公司,各级行政单位,有层级的菜单,还有我们的文件浏览器等等。
上面图片我们可以想象是一颗完整的树,A相当于主干,BC相当于从主干分离出来的分支,分支上面可以有分支,也可以有叶子。 分支把主干和叶子联系在了一起。这里有三个对象是我们今天组合模式需要探讨的:“主干”,“分支”,“叶子”。
组合模式分为:安全式组合模式的结构 和 透明式组合模式的结构
安全式组合模式的结构
安全组合模式中,在抽象构件Component中没有声明任何用于管理成员对象的方法,而是在Composite类中声明并实现这些方法。这种做法是安全的,因为根本不向叶子对象提供这些管理成员对象的方法,对于叶子对象,客户端不可能调用到这些方法。代码如下:
抽象组件(Component):
叶子(Leaf):
树干(Composite):
客户端进行组合:
安全式组合模式在对于客户来说,不能直接操作树叶(Company),只能通过树干(Composite)进行操作,对客户不够透明,但是在这里比较安全,不至于客户直接操作树叶报错。
透明式组合模式的结构
透明组合模式中,抽象构件Component中声明了所有用于管理成员对象的方法,包括add()、remove()以及getChild()等方法,这样做的好处是确保所有的构件类都有相同的接口。在客户端看来,叶子对象与容器对象所提供的方法是一致的,客户端可以相同地对待所有的对象。透明组合模式也是组合模式的标准形式。如图:
组件(Component):
叶子(Leaf):
树干(Composite):
客户端:
透明式组合模式,客户端可以直接操作叶子节点,但是叶子节点已经是最终节点,里面不可能再有下级目录,虽说透明对客户透明, 但是没有任何实际意义。
经典案例分析:
请看下面jdk自带的源码:
图片中的JDK源码各位估计再熟悉不过了。
JDK中map有个Entry接口,就相当于我们文章里面的组件(Component),里面有各种抽象方法(框框里面)。
JDK1.8之前,HashMap底层利用数组和链表实现,链表里面存储的对象就是Node对象,node对象正式我们文章的叶子,Node实现了我们Entry接口,node里面有node,节点里面有节点,Node 是个非常经典的组合模式。