组合模式/composite模式/对象结构型模式

组合模式/composite模式/对象结构型

意图

将对象组合成树形结构以表示“整体——部分”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。

动机

Composite模式,关键是一个抽象类(组件),既可以代表对象(叶子节点),又可以代表组合(中间节点)。使用组合模式,我们能把相同的操作应用到组合和个别对象上。
通过让组件包含管理子节点和叶节点的操作,换取了对客户的透明性。

透明性和安全性的抉择

组合模式,使得用户对叶子节点和中间节点一视同仁,但是用户可以叶子节点进行只有中间节点才有的操作,有失安全性。
在具体实现组合模式时,可以在抽象类或结构中,默认提供“不可操作”的方法,子类不重写,即不可使用。

java实现要素:组件(component)+组合(composite)+树(结构)

  1. 组件,是接口定义,组合要实现组件(无论组合是否为叶子)。
  2. 组合是对组件的实现,组件的实现有两种:组合和叶节点。组合有孩子,孩子既可以是组合,又可以是叶节点;叶子节点为末尾节点,不可以有孩子。
  3. 通过组合+叶节点,实现一个树形的结构。

代码实现

/**
 * 组件接口,为组合中所有对象定义接口,无论是组合还是叶子。
 * 并且添加了一些默认行为。
 */
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)

posted @ 2016-09-23 18:19  toto怎么会喝醉  阅读(503)  评论(4编辑  收藏  举报