组合模式:
将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
结构图:
实例:
透明方式:
leaf中也有add和remove叫做透明方式,在component中声明所有用来管理子对象的方法,其中包括add、remove等。这样实现component接口的所有子类都具备了add和remove。这样的好处是叶节点和枝节点对外界没有区别,他们具备完全一致的行为接口。
但问题也很明显,因为leaf类本身不具备add和remove等功能,所以实现他是没有意义的。
透明模式的特点:
就是将组合对象所有的公共方法都定义在了抽象组件内,
优点:是客户端无需分辨当前对象是属于树枝节点还是叶子节点,因为它们具备了完全一致的接口,
缺点:叶子节点得到到了一些不属于它的方法.。树叶是不存在子类的,因此Component声明的一些方法对于树叶来说是不适用的。这样也就带来了一些安全性问题。
安全方式:
在Component接口中不去声明Add和Remove方法,那么子类的Leaf也就不需要去实现它,而是在Composite声明所有用来管理子类对象的方法。这样做不会出现Leaf做无用功的问题,不过由于不够透明,所以树叶和树枝类将不具有相同的接口,客户端的调用需要做相应的判断,带来了不便。
优点:安全组合模式只是规定了系统各个层次的最基础的一致性行为,而把组合(树节点)本身的方法(如树枝节点管理子类的addChild等方法)放到自身当中。这样就避免了上一种方式的安全性问题
缺点:由于叶子和分支有不同的接口,所以又失去了透明性。
透明模式VS安全模式:在这一模式中,相对于安全性,我们比较强调透明性。对于第一种方式中叶子节点不需要的方法可以使用空处理或者异常报告的方式来解决。
优点:
-
定义了包含基本对象和组合对象的类层次结构。基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断的递归下去,客户端代码中,任何用到基本对象的地方都可以使用组合对象。
-
用户不用关心到底是处理一个叶节点还是处理一个组合组件,也就是用不着为定义组合而写一些选择判断语句了。(让客户端忽略了层次的差异,方便对整个层次结构进行控制)
-
组合模式让客户端可以一致的使用组合结构和单个对象。
-
简化客户端代码
-
符合开闭原则
缺点:
-
限制类型时较为复杂
-
使设计变得更加抽象
-
在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
适用场景:
当发现需求中是体现部分与整体的层次结构时;以及你希望用户可以忽略组合对象与单个对象的不同,统一的使用组合结构中的所有对象时,就应该考虑用组合模式了。
当处理一个树型结构时。