组合模式
1.组合模式含义
组合模式,将对象组合成树形结以表示部分-整体
的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性
组合模式可以简单的理解为将各个单独的小对象,通过组合模式,组合成一个大的对象,这个大的对象里面包含了父子节点这样的结构。如果实现过树形结构需求的小伙伴应该能比较快速的接受这个模式。
2.代码示例
下面先以一个简单的代码示例,来展示一下组合模式的代码结构
2.1Component类
Component类是组合对象的抽象类
public abstract class Component {protected String name;public Component(String name) {this.name = name;}public abstract void add(Component component);public abstract void remove(Component component);public abstract void display(int depth);
}
2.2Leaf类
Leaf类是Component的子类,是叶子节点类,叶子节点只有对象本身的名称信息,没有子节点信息
public class Leaf extends Component{public Leaf(String name) {super(name);}@Overridepublic void add(Component component) {System.out.println("新增一个叶子节点");}@Overridepublic void remove(Component component) {System.out.println("删除一个叶子节点");}@Overridepublic void display(int depth) {for (int i = 0; i < depth; i++) {System.out.print("-");}System.out.println(name);}
}
2.3 Composite类
Composite类是Component类的子类,是根节点或者中间节点类,既有节点本身的名称信息,也有叶子节点的信息
public class Composite extends Component{private List<Component> childrenList = new ArrayList<>();public Composite(String name) {super(name);}@Overridepublic void add(Component component) {childrenList.add(component);}@Overridepublic void remove(Component component) {childrenList.remove(component);}@Overridepublic void display(int depth) {for (int i = 0; i < depth; i++) {System.out.print("-");}System.out.println(name);for (Component component : childrenList) {component.display(depth + 4);}}
}
2.4测试类
public class MainApp {public static void main(String[] args) {Composite root = new Composite("root");root.add(new Leaf("root的A叶子"));root.add(new Leaf("root的B叶子"));Composite comp = new Composite("root的X子节点");comp.add(new Leaf("X子节点的叶子节点C"));comp.add(new Leaf("X子节点的叶子节点D"));root.add(comp);Composite compY = new Composite("X节点的Y子节点");compY.add(new Leaf("Y子节点的叶子节点E"));compY.add(new Leaf("Y子节点的叶子节点F"));comp.add(compY);Leaf leaf = new Leaf("叶子G");root.add(leaf);root.remove(leaf);root.display(2);}
}
运行结果
–root
------root的A叶子
------root的B叶子
------root的X子节点
----------X子节点的叶子节点C
----------X子节点的叶子节点D
----------X节点的Y子节点
--------------Y子节点的叶子节点E
--------------Y子节点的叶子节点F
这个结果其实就是如下这个图片的展示效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MgmN3Auh-1689863412527)(C:\Users\dalei\AppData\Roaming\Typora\typora-user-images\image-20230719213141794.png)]
就是这样的树形结构。
将各个单独的对象,组合起来,组合成这样的树形结构,这就是组合模式
3.总结
当我们的需求中是体现部分与整体层次的结构时,以及希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就可以考虑使用组合模式了。
组合模式中,Leaf叶子节点并没有子节点了,但是却还有add和remove方法,这样做看似有些多余,因为即使调用了子节点的add或remove方法也不会真的增加和删除孩子节点。
此处这样实现其实是涉及到透明方式
的选择。也就是说在Component中所声明的用来管理子对象的方法,其中包括add和remove等。这样实现Component接口的所有子类都聚类了add和remove。这样做的好处是叶子节点和中间节点对于外界来说没有区别,它们具备完全一致的行为接口。但是问题也很明显,因为叶子节点的add和remove功能并没有效果。
如果希望在叶子节点中不要实现add和remove方法,就要以安全方式
来使用,也就是在Component类中不去声明add和remove,那么子类也就不需要实现这些方法。取而代之的是将这些方法放到中间节点去实现,这样做就不会有上面的透明方式实现的问题了。但是也正因为不够透明,所以叶子节点和中间节点将不会有相同的方法接口,客户端在调用的时候需要做相应的判断,使用上不太方便。
但是其实透明方式
和不透明方式
实现组合模式都是可以的,看具体开发中哪种方法更适合即可。
实现这些方法。取而代之的是将这些方法放到中间节点去实现,这样做就不会有上面的透明方式实现的问题了。但是也正因为不够透明,所以叶子节点和中间节点将不会有相同的方法接口,客户端在调用的时候需要做相应的判断,使用上不太方便。
但是其实透明方式
和不透明方式
实现组合模式都是可以的,看具体开发中哪种方法更适合即可。
组合模式的好处是:基本你对象可以被组合成更复杂的对象,而这个组合对象又可以被组合,这样不断递归下去,客户端任何用到基本对象的地方都可以使用组合对象了。