介绍
合成模式属于对象的结构模式,有时又叫做部分-整体(Part-Whole)模式。合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式可以使客户端将单纯元素与复合元素同等看待。
模式角色
合成模式有以下角色:
- Component(抽象构件),这是一个抽象角色,它给参加组合的对象规定一个接口。这个角色给出共有的接口及其默认行为。
- Composite(树枝构件),拥有下一级树叶节点对象 , 同时对树叶节点对象进行管理。
- Leaf(树叶构件),没有下一级节点对象 , 树结构最末端 , 由该对象组成上一级的树枝节点对象。
模式结构图
- 安全式合成模式结构图
- 透明式合成模式结构图
模式实现
合成模式种类分为安全式和透明式 , 主要区分在于树枝构件中 , 管理方法是在抽象构件中定义 , 还是直接在树枝构件中定义。
- 安全式合成模式,在树枝构件中直接定义管理方法 , 这样避免在树叶构件中进行定义 。
- 透明式合成模式,管理方法在抽象构件中定义 , 同时树叶节点需要用平庸的方式实现管理方法 。
安全式合成模式
/**
* 抽象构件
*/
public interface Component {
boolean isBranch();
// 某个逻辑或业务
void doSomething();
}
/**
* 树枝构件
*/
public class Branch implements Component {
private final List<Component> componentList = new ArrayList<>();
@Override
public boolean isBranch() {
return true;
}
@Override
public void doSomething() {
// 功能or业务逻辑
List<Component> components = components();
java.util.Iterator<Component> iterator = components.iterator();
while (iterator.hasNext()) {
iterator.next().doSomething();
}
}
public void add(Component component) {
componentList.add(component);
}
public void remove(Component component) {
componentList.remove(component);
}
public List<Component> components() {
return componentList;
}
}
/**
* 树叶构件
*/
public class Leaf implements Component {
@Override
public boolean isBranch() {
return false;
}
@Override
public void doSomething() {
// 功能or业务逻辑
}
}
透明式合成模式
/**
* 抽象构件
*/
public interface Component {
boolean isBranch();
void add(Component component);
void remove(Component component);
List<Component> components();
// 某个逻辑或业务
void doSomething();
}
/**
* 树枝构件
*/
public class Branch implements Component {
private final List<Component> componentList = new ArrayList<>();
@Override
public boolean isBranch() {
return true;
}
@Override
public void doSomething() {
// 功能or业务逻辑
List<Component> components = components();
java.util.Iterator<Component> iterator = components.iterator();
while (iterator.hasNext()) {
iterator.next().doSomething();
}
}
@Override
public void add(Component component) {
componentList.add(component);
}
@Override
public void remove(Component component) {
componentList.remove(component);
}
@Override
public List<Component> components() {
return componentList;
}
}
/**
* 树叶构件
*/
public class Leaf implements Component {
@Override
public boolean isBranch() {
return false;
}
@Override
public void add(Component component) {
// empty
}
@Override
public void remove(Component component) {
// empty
}
@Override
public List<Component> components() {
return null;
}
@Override
public void doSomething() {
// 功能or业务逻辑
}
}
使用场景
经常会出现有树结构的情况 , 其中由单独的对象或者单独对象组成的合成对象组成 , 此时就需要利用一种方式来完成树结构的构建工作 。
合成模式提供一个树结构中所有对象的统一接口 , 规范树中单独对象和合成对象的构建过程 , 合成模式更像一个数据结构 。
模式结构方向性
因合成模式一般是一个树结构的数据类型。而树结构有方向性。
合成模式(树结构)的方向性 , 分为三类 , 向下、向上、双向 。
- 向下性 , 一般情况结构为向下性 , 也就是父类节点中包含子节点的引用 , 而子节点并不知道它的父节点 。
- 向上性 , 每一个子节点中都包含一个父类节点的引用 , 同时父节点是不知道子节点的情况 。
- 双向性 , 父节点和子节点都包含有对方的引用 , 当需要使用时 , 可以利用引用找到对方。
合成模式使用案例
如文件夹和文件、图形接口中的容器类ViewGroup和与视图类View、公司和部门…