![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/38d605679dd11db09c6f4f1c7c5c09cb.png)
魔战已经完结。成功登顶。占领敌军最高峰。
二十三、设计模式之组合模式
“组合模式”也被称为“部分整体模式”该模式属于结构型模式的一种。
将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
所属类型 | 定义 |
---|---|
结构型 | 将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 |
能帮我们干什么?
主要解决什么问题?
主要解决的是 它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
优缺点
优点
1、高层模块调用简单。
2、节点自由增加。
缺点:
在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
使用的场景
以下情况下适用Composite模式:
1.你想表示对象的部分-整体层次结构
2.你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
部分、整体场景,如树形菜单,文件、文件夹的管理。
理解
讲解该模式之前先带大家熟悉一下“树形结构”。相信大家对“树形结构”不会太陌生,如果你刚好不太了解的话可以想一下大树,一颗树它分别有树根、树枝、树叶,正好树形结构中也有根节点、子节点(非叶子节点)、叶子节点。
组合模式就运用了树形结构,该模式的核心思想是:将多个对象组合成树形结构,以此结构来表示“整体-部分”之间的层次关系。
实现
角色
- Component:组合模式中的“根节点”,可以是接口、抽象类、普通类,该类中定义了其子类的所有共性内容,并且该类中还存在着用于访问和管理它子部件的方法。
- Leaf:组合中的叶子节点,也就是最末端的节点,该节点下不会再有子节点。
- Composite:非叶子节点,它的作用是存储子部件,并且在Composite中实现了对子部件的相关操作。
组合模式
如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。
关键代码:树枝内部组合该接口,并且含有内部属性 List,里面放 Component。
实现难度: ⭐️ ⭐️ ⭐️ ⭐️
举例:
java/com/kongxiang/raindrop/dp/type/structure/composite · master · 无难事者若执 / 23种设计模式 · GitCode
叶节点和组合节点。
component
public abstract class Component {
protected String name;
public Component(String name){
this.name = name;
}
public abstract void draw();
public abstract void add(Component component);
public abstract void remove(Component component);
}
leaf
public class Leaf extends Component {
public Leaf(String name) {
super(name);
}
@Override
public void draw() {
System.out.println(this.name);
}
@Override
public void add(Component component) {
throw new IllegalArgumentException("叶节点不能添加组件");
}
@Override
public void remove(Component component) {
throw new IllegalArgumentException("叶节点不能移除组件");
}
}
composite
public class Composite extends Component {
private List<Component> componentList = new ArrayList<>();
public Composite(String name) {
super(name);
}
@Override
public void draw() {
for (Component com :
componentList) {
com.draw();
}
}
@Override
public void add(Component component) {
this.componentList.add(component);
}
@Override
public void remove(Component component) {
this.componentList.remove(component);
}
}
client
public static void main(String[] args) {
Leaf leaf = new Leaf("张三”");
Leaf leaf1 = new Leaf("张4”");
Leaf leaf2 = new Leaf("张5”");
Leaf leaf3 = new Leaf("张6”");
Leaf leaf4 = new Leaf("张7”");
Composite composite = new Composite("组1");
composite.add(leaf);
composite.add(leaf1);
Composite composite2 = new Composite("组2");
composite2.add(leaf2);
composite2.add(leaf3);
Composite composite3 = new Composite("组3");
composite3.add(leaf4);
composite.add(composite2);
composite2.add(composite3);
composite.draw();
}
总结
组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以像处理简单元素一样来处理复杂元素。
如果你想要创建层次结构,并可以在其中以相同的方式对待所有元素,那么组合模式就是最理想的选择。本章使用了一个文件系统的例子来举例说明了组合模式的用途。在这个例子中,文件和目录都执行相同的接口,这是组合模式的关键。通过执行相同的接口,你就可以用相同的方式对待文件和目录,从而实现将文件或者目录储存为目录的子级元素。