1、意图
将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。
2、适用性
以下情况使用Composite模式
(1)你想表示对象的部分-整体层次结构
(2)你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象
3、参与者
(1)Component:为组合中的对象声明接口;在适当的情况下,实现所有类共有接口的缺省行为;声明一个接口用于访问和管理Component的子组件;在递归结构中定义一个接口,用于访问一个父部件,并在合适的情况下实现它。
(2)Leaf:在组合中表示叶节点对象,叶节点没有子节点;在组合中定义图元对象的行为
(3)Composite:定义有子部件的那些部件的行为;存储子部件;在Component接口实现与与子部件有关的操作
(4)Client:通过Component接口操纵组合部件的对象。
UML类图表示为
Java代码表示为:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package javatest;
import java.util.List;
import java.util.ArrayList;
/*component*/
interface Graphics
{
public void print();
}
/*composite*/
class CompositeGraphics implements Graphics
{
private List<Graphics> childGraphics = new ArrayList<Graphics>();
@Override
public void print()
{
for (Graphics graphics:childGraphics) {
graphics.print();
}
}
public void add(Graphics graphics)
{
childGraphics.add(graphics);
}
}
/*Leaf*/
class Ellipse implements Graphics
{
@Override
public void print()
{
System.out.println("Ellipse");
}
}
/*Client*/
public class JavaTest
{
public static void main(String[] args)
{
Ellipse ellipse1 = new Ellipse();
Ellipse ellipse2 = new Ellipse();
Ellipse ellipse3 = new Ellipse();
Ellipse ellipse4 = new Ellipse();
CompositeGraphics graphics = new CompositeGraphics();
CompositeGraphics graphics1 = new CompositeGraphics();
CompositeGraphics graphics2 = new CompositeGraphics();
graphics1.add(ellipse1);
graphics1.add(ellipse2);
graphics1.add(ellipse3);
graphics2.add(ellipse4);
graphics.add(graphics1);
graphics.add(graphics2);
graphics.print();
}
}
4、协作
用户使用Component类接口与组合结构中的对象进行交互。如果接收者是叶节点,则直接处理请求,如果接收者是Composite,它通常将请求发送给它的子部件,在转发请求之前与/或之后可能执行一些辅助操作。
5、效果
(1)定义了包含基本对象和组合对象的类层次结构,基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断的递归下去。客户代码中,任何用到基本对象的地方都可以使用组合对象。
(2)简化客户代码,客户可以一致地使用组合结构和单个对象。通常用户不知道(也不关心)处理的是一个叶节点还是一个组合组合。这就简化了客户代码,因为在定义组合地那些类中不需要写一些充斥着选择语句 的函数
(3)使得更容易增加新类型的组件,新定义的Composite或Leaf子类自动地与已有的结构和客户代码一起工作,客户程序不需因新的Composite类而改变。
(4)使你的设计变得更加一般化,容易增加新组件也会产生一些问题,那就是很难限制组合中的组件。有时你希望一个组合中能有某些特定的组合 。使用Composite时,你不能依赖类型系统施加这些约束,而必须在运行时刻进行检查。
6、相关模式
通常部件-父部件连接用于Responsibility of Chain 模式
Decorator模式经常与Composite模式一起使用。当装饰和组合一起使用时,它们通常有一个公共的父类。因些装饰必须支持具有Add、Remove和GetChild操作的Component接口。
Flyweight让你共享组件,但不再能引用他们的父部件。
Iterator可用来遍历Composite。
Visitor将本来应该分布在Composite和Leaf类中的操作和行为局部化。