组合模式/composite模式/对象结构型模式
组合模式/composite模式/对象结构型
意图
将对象组合成树形结构以表示“整体——部分”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。
动机
Composite模式,关键是一个抽象类(组件),既可以代表对象(叶子节点),又可以代表组合(中间节点)。使用组合模式,我们能把相同的操作应用到组合和个别对象上。
通过让组件包含管理子节点和叶节点的操作,换取了对客户的透明性。
透明性和安全性的抉择
组合模式,使得用户对叶子节点和中间节点一视同仁,但是用户可以叶子节点进行只有中间节点才有的操作,有失安全性。
在具体实现组合模式时,可以在抽象类或结构中,默认提供“不可操作”的方法,子类不重写,即不可使用。
java实现要素:组件(component)+组合(composite)+树(结构)
- 组件,是接口定义,组合要实现组件(无论组合是否为叶子)。
- 组合是对组件的实现,组件的实现有两种:组合和叶节点。组合有孩子,孩子既可以是组合,又可以是叶节点;叶子节点为末尾节点,不可以有孩子。
- 通过组合+叶节点,实现一个树形的结构。
代码实现
/**
* 组件接口,为组合中所有对象定义接口,无论是组合还是叶子。
* 并且添加了一些默认行为。
*/
public interface Component {
void operation();
default void add(Component component){
throw new RuntimeException("不支持此操作");
}
default void remove(Component component){
throw new RuntimeException("不支持此操作");
}
default List<Component> getChildren(){
throw new RuntimeException("不支持此操作");
}
}
/**
* 定义组件的行为,这种组件具有子节点
*
*/
public class Composite implements Component {
List<Component> children = new ArrayList<>();
@Override
public synchronized void operation() {
getChildren().forEach(s -> s.operation());
}
@Override
public synchronized void add(Component component) {
children.add(component);
}
@Override
public synchronized void remove(Component component) {
children.remove(component);
}
@Override
public List<Component> getChildren() {
return children;
}
}
/**
* 定义叶子节点操作,定义组合内的元素行为。
* 对于叶子节点,增删改节点操作没有意义。
*
*/
public class Leaf implements Component{
@Override
public void operation() {
System.out.println("这是叶子"+UUID.randomUUID());
}
}
//测试
public class Test {
public static void main(String[] args) {
Composite root = new Composite();
root.add(new Leaf());
root.add(new Leaf());
Composite compX = new Composite();
compX.add(new Leaf());
compX.add(new Leaf());
root.add(compX);
Composite compXY = new Composite();
compXY.add(new Leaf());
compXY.add(new Leaf());
compX.add(compXY);
root.operation();
}
}
JDK中的迭代器模式
让使用者把单独的对象和组合对象混用
javax.swing.JComponent#add(Component)
java.awt.Container#add(Component)
java.util.Map#putAll(Map)
java.util.List#addAll(Collection)
java.util.Set#addAll(Collection)
I am a slow walker, but I never walk backwards.