一、什么是组合模式?
组合模式,又称为部分-整体模式,使用户对单个对象和组合对象具有一致的访问性,符合里氏代换原则。
如下图中的树枝和树叶,它们都是实现了Composite的类,本质上都是属于同一种数据类型
二、如何实现组合模式?
有2种实现方式
- 透明方式:抽象类实现所有子类的方法
- 隐藏方式:抽象类只实现所有子类的共同方法
下面将使用代码实现上图所示的结构
(透明方式):
public class CompositeDemo {
public static void main(String[] args) {
// 新建树对象
Branch tree = new Branch("树");
// 新建树枝对象
Branch branch1 = new Branch("树枝1");
Branch branch2 = new Branch("树枝2");
// 新建5个树叶对象
Leaf leaf1 = new Leaf("树叶1");
Leaf leaf2 = new Leaf("树叶2");
Leaf leaf3 = new Leaf("树叶3");
Leaf leaf4 = new Leaf("树叶4");
Leaf leaf5 = new Leaf("树叶5");
// 把对象都添加到树中
tree.add(leaf1);
tree.add(branch1);
branch1.add(leaf2);
branch1.add(leaf3);
branch1.add(branch2);
branch2.add(leaf4);
branch2.add(leaf5);
// 展示所有树叶
tree.show();
}
}
// 创建抽象类(透明方式)
interface Composite{
// 增加子节点方法
void add(Composite composite);
// 删除子节点方法
void remove(Composite composite);
// 获取子节点方法
Composite getChild(int i);
// 展示子节点方法
void show();
}
// 树叶类对象
class Leaf implements Composite {
// 树叶名称
private String leadName;
Leaf(String name){
this.leadName = name;
}
@Override
public void add(Composite composite) {
//树枝无此方法,所以不实现
}
@Override
public void remove(Composite composite) {
//树枝无此方法,所以不实现
}
@Override
public Composite getChild(int i) {
//树枝无此方法,所以不实现
return null;
}
@Override
public void show() {
System.out.println(leadName);
}
}
// 树枝类对象
class Branch implements Composite {
// 树枝名称
private String branchName;
// 树枝下面的树叶
private List<Composite> children = new ArrayList<>();
Branch(String name) {
this.branchName = name;
}
/**
* 增加树叶
*/
@Override
public void add(Composite composite) {
children.add(composite);
}
/**
* 删除树叶
*/
@Override
public void remove(Composite composite) {
children.remove(composite);
}
/**
* 获取下一级节点
*/
@Override
public Composite getChild(int i) {
return children.get(i);
}
/**
*递归展示所有节点
*/
@Override
public void show() {
System.out.println("这是:"+branchName+"包含下面节点");
for (Composite composite : children) {
composite.show();
}
}
}
输出结果如下
这是:树包含下面节点
树叶1
这是:树枝1包含下面节点
树叶2
树叶3
这是:树枝2包含下面节点
树叶4
树叶5
改成隐藏方式,接口只需要实现共同的方法即可。
// 创建抽象类(隐藏方式)
interface Composite{
// 展示子节点方法,所有的子类都有的共同方法
void show();
}
三、组合模式有什么优缺点?
在组合模式中,整个树形结构中的对象都属于同一种类型,带来的好处就是用户不需要辨别是树枝节点还是叶子节点,可以直接进行操作,给用户的使用带来极大的便利。
优点:
- 组合模式使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,这简化了客户端代码;
- 更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码,满足“开闭原则”;
其主要缺点是:
- 设计较复杂,客户端需要花更多时间理清类之间的层次关系;
- 不容易限制容器中的构件;
- 不容易用继承的方法来增加构件的新功能;