结构型 组合模式

2020/06/01

又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。

什么时候用?

1、你想表示对象的部分-整体层次关系(树形结构)

2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

组合模式与之前讲的装饰器模式很像,都是通过在类中存储成员变量来完成一些功能上的扩展,那么它们之间有什么不同呢?

  • 每一个装饰器类只有含有一个组件,即没有对象聚合,而每个组合类可以含有多个组件,即 Composite。
  • 装饰器模式倾向于在原有对象的基础上添加新的功能,组合模式倾向于对原有对象的功能进行组合使用。

业务场景?

考虑下面的场景:

你被要求开发一个简单的图形库。初始要求是:

  • 图形库必须能够处理基础图形,如线和圆。
  • 图形库必须允许复合和基础图形的递归复合,以便绘图可以由多种图形组成。
  • 需要提供操作以允许添加,移除,显示和图形组件。

思路很清晰,图形分为基础图形和组合图形,用组合模式再合适不过了。

用 Java 代码表示:

基础图形:

abstract class GraphicsObject {
    public abstract void draw();
    public void add(GraphicsObject object) {
	throw new UnsupportedOperationException();
    }
    public void remove(GraphicsObject object) {
	throw new UnsupportedOperationException();
    }
}

class Circle extends GraphicsObject {
    public void draw() {
	System.out.println("draw circle");
    }
}

class Line extends GraphicsObject {
    public void draw() {
	System.out.println("draw line");
    }	
}

class Rectangle extends GraphicsObject {
    public void draw() {
	System.out.println("draw rectangle");
    }	
}

组合图形:

import java.util.ArrayList;

class ComposedGraphicsObject extends GraphicsObject {
    private ArrayList<GraphicsObject> components;
    public ComposedGraphicsObject() {
	components = new ArrayList<GraphicsObject>();
    }
    @Override
    public void add(GraphicsObject object) {
	components.add(object);
    }
    @Override
    public void remove(GraphicsObject object) {
	components.remove(object);
    }
    public void draw() {
	for(GraphicsObject component: components) {
        	component.draw();
	}
    }
}

图形库:

import java.util.ArrayList;

class GraphicsLibrary {
    private ArrayList<GraphicsObject> components;
    public GraphicsLibrary() {
	components = new ArrayList<GraphicsObject>();
	initData();
    }
    public void initData() {
	GraphicsObject line = new Line();
	GraphicsObject circle = new Circle();
	GraphicsObject rectangle = new Rectangle();

	//添加基础图形到图形库中
	components.add(line);
	components.add(circle);
	components.add(rectangle);
		
	//创建并添加组合图形到图形库中
	GraphicsObject composite = new ComposedGraphicsObject();
	composite.add(line);
	composite.add(rectangle);
	components.add(composite);

    }
    public ArrayList<GraphicsObject> getGraphicsObjects() {
	return components;
    }
}

客户端调用:

class Client {
    public static void main(String[] args) {
	GraphicsLibrary gl = new GraphicsLibrary();

	//使用基础图形 line
	System.out.println("第一个图形:");
	gl.getGraphicsObjects().get(0).draw();

	//使用组合图形 composite
	System.out.println("第二个图形:");
	gl.getGraphicsObjects().get(3).draw();
    }
}

参考

设计模式之组合模式

Post Directory