核心理解

适用于树形结构,整体和部分有相似的结构,在操作时可以被一致对待。

举个例子

公司的人员分布结构
image.png

如果不使用组合模式

管理者:
image.png
image.png

职员:
image.png
使用:
image.png

有两个弊端:

  • 在管理者和职员中,name, job, work重复了
  • 管理者需要对底下的其他管理者和职员区别对待(addManager或者addEmployee)

使用组合模式

首先,抽象出一个Component类,将重复的字段放进该Component中:
image.png
管理者继承该抽象类:
image.png
职员也继承该对象:
image.png

使用如下:
image.png
成功的解决了不使用组合模式的两个问题:

  • 重复的字段放进了父类中;
  • 管理者下边的其他管理者和普通员工不需要区别对待了,都是Component,直接调用addComponent即可。

组合模式中的透明模式

以上代码中,有个问题,就是Employee虽然继承了父类的addComponent和removeComponent方法,但是仅仅提供了空实现,这违背了接口隔离原则。

即:客户端不应依赖它不需要的接口。

这种方式也有优点,Manager和Employee类具备完全一致的行为接口,调用者可以一致对待这两个类,无需做区分。

缺点就是违背了接口隔离原则,客户端甚至可以通过Employee调用addComponent和removeComponent方法,导致程序出错,所以不安全。

组合模式中的安全模式

安全模式就是将父类中的addComponent和removeComponent先移除(因为Employee不需要),然后让Manager自己去实现这两个方法。

优点就是安全了,且符合接口隔离原则。

缺点就是Manager和Employee不具备相同接口了,无法将Manager和Employee统一声明成Component类了。使用就不方便了。

用透明模式还是安全模式

根据实际情况定,但是大多数情况用透明模式,虽然有点不安全,但是用起来方便。