考虑实现一个管理公司组织架构的系统,公司下可能包含子公司,子公司下包含CEO等最高管理者和部门,部门下又包含部门管理者和小部门,等等。抽象成数据结构,就是一个树形结构。
如果为每一种尸体类型都定义一个类,那至少要包括总公司/子公司/部门/员工,这四个类。每个类的所包含的成员也有很大不同,均需要定制。而且随着类型越来越多,这种组合性的复杂的是成指数上升的。
上面说的这种复杂性,主要来自于类别之间的差异性。如果能忽略掉差异,将所有的实体统一处理,那问题将被大大的简化。组合模式就是擅长做这件事情的模式。
组合模式(Composite Pattern):组合多个对象形成树形结构以表示具有“整体—部分”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,组合模式又可以称为“整体—部分”(Part-Whole)模式,它是一种对象结构型模式。
在上面的模型中,员工就是个叶子结点,不包含任何子节点。其他的都是容器节点,包含若干类型和个数的子节点。忽略掉这些差异后,通过一个抽象类,来充当所有节点的抽象父类。
![](https://i-blog.csdnimg.cn/blog_migrate/657f905f85ca5c16fa25ed29560d39ac.png)
父类中,定义了子元素的集合和操作。子类根据不同类型,分别实现不同的部分。父类定义的子元素类型还是本身,差异就是在此处消除掉的,所有的节点都是抽象父类类型,统一处理。
在细节上,有两种实现方式。一种是如上图将所有方法定义在抽象类中。所有子类均需要实现,不需要的方法可以用异常处理。另一种方式是抽象类中只定义通用成员和方法,子类中定义自己需要的成员和方法。两种各有利弊:第一种复杂不安全;第二种不透明,在使用时,还需要依赖具体类型。
总结:
优点:
- 忽略差异,客户端编码简单化
- 扩展容易,几乎不必修改现有类,符合开闭原则
- 可以组成非常复杂的树形结构,但是控制却很简单
- 容器中很难多包含的类型进行限制。