组合模式:将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性.
    适用环境:

u       你想表示对象的部分-整体层次结构。

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

Composite好处
:
1.使客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不必关系自己处理的是单个对象还是整个组合结构,这就简化了客户端代码。
2.更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。

组合模式的组成

1)         抽象构件角色Component:它为组合中的对象声明接口,也可以为共有接口实现缺省行为。

2)       树叶构件角色Leaf:在组合中表示叶节点对象——没有子节点,实现抽象构件角色声明的接口。

3)       树枝构件角色Composite:在组合中表示分支节点对象——有子节点,实现抽象构件角色声明的接口;存储子部件。

下图为组合模式的类图表示。
comp1.bmp
三、安全性与透明性

组合模式中必须提供对子对象的管理方法,不然无法完成对子对象的添加删除等等操作,也就失去了灵活性和扩展性。但是管理方法是在Component中就声明还是在Composite中声明呢?

一种方式是在Component里面声明所有的用来管理子类对象的方法,以达到Component接口的最大化(如下图所示)。目的就是为了使客户看来在接口层次上树叶和分支没有区别——透明性。但树叶是不存在子类的,因此Component声明的一些方法对于树叶来说是不适用的。这样也就带来了一些安全性问题。
   另一种方式就是只在Composite里面声明所有的用来管理子类对象的方法(如下图所示)。这样就避免了上一种方式的安全性问题,但是由于叶子和分支有不同的接口,所以又失去了透明性。
  《设计模式》一书认为:在这一模式中,相对于安全性,我们比较强调透明性。对于第一种方式中叶子节点内不需要的方法可以使用空处理或者异常报告的方式来解决。
如何使用Composite?
首先定义一个接口或抽象类Component

package composite;
import java.util.Iterator;
public abstract class Equipment{
    
//名称
    private String name;
    
//价格
    public abstract double netPrice();
    
//增加一个部件
    public boolean add(Equipment equ){
        
return false;
    }

    
//删除一个部件
    public boolean remove(Equipment equ){
        
return false;
    }

    
//迭代指针
    public Iterator iter(){
        
return null;
    }

    
//构造方法
    public Equipment(String name){
        
this.name=name;
    }

}
Disk类Leaf角色
package composite;
public class Disk extends Equipment{
    
//构造方法
    public Disk(String name){
        
super(name);
    }

    
//定价
    public double netPrice(){
        
return 1.2;
    }

}
CompositeEquipment 类Composite角色
package composite;
import java.util.*;
public abstract class CompositeEquipment  extends Equipment{
    
private List equipment=new ArrayList();
    
public CompositeEquipment(String name){
        
super(name);
    }

    
public boolean add(Equipment equ){
        equipment.add(equ);
        
return true;
    }

    
public boolean remove(Equipment equ){
        equipment.remove(equ);
        
return true;
    }

    
    
public Iterator iter(){
        
return equipment.iterator();
    }

    
    
public double netPrice(){
        
double netprice=0;
        Iterator it
=equipment.iterator();
        
while(it.hasNext()){
            netprice
+=((Equipment)it.next()).netPrice();
        }

        
return netprice;
    }

    
}
CompositeEquipment的两个具体类
package composite;
public class Chassis extends CompositeEquipment{
    
public Chassis(String name){
        
super(name);
    }

    
    
public double netPrice(){
        
return 3.0+super.netPrice();
    }

    
}
package composite;
public class Cabinet extends CompositeEquipment{
    
public Cabinet(String name){
        
super(name);
    }

    
    
public double netPrice(){
        
return 3.0+super.netPrice();
    }

    
}
运行类
package composite;
public class Composite{
    
public static void main(String[] args){
        Cabinet cabinet
=new Cabinet("Tomer");
        Chassis chassis
=new Chassis("PC chassis");
        
        cabinet.add(chassis);
        chassis.add(
new Disk("120Gb"));
        
        System.out.println(cabinet.netPrice());
    }

}
运行结果如:
7.2
Press any key to continue...


参考资料:http://blog.csdn.net/ai92/archive/2005/02/23/298336.aspx
 http://www.lvjiyong.com/books/DesignPatterns/21.html
http://www.jdon.com/designpatterns/composite.htm