1.组合模式是整体与部分的关系,一个典型的应用就是树型结构,组合模式可以抽象出三种角色,分别为抽象构建角色(Component)、树枝构建角色(Composite)、树叶构建角色(Leaf).

抽象构建角色:这是一个抽象的角色,它给参加组合的对象规定了统一的接口,给出了公有的接口和行为。

树枝构建角色:代表参加组合的有子类的对象,并给出树枝构建对象的行为。

树叶构建角色:代表参加组合的树叶对象,即没有子节点的对象。

      下面给出一个例子来说明,曾经我做项目的时候,遇到过这样的一种需求,计算某个学生的分数,但是这个分数由A,B,C三部分组成,它们的比重分别为0.3,0.4,0.3,而A又由a1(0.5),a2(0.5),B又由b1(0.3),b2(0.7),C又由c1(0.4),c2(0.6)组成括号后面代表各自所占得比重,最后a1,a2,b1,b2,c1,c2的成绩分别为80,70,95,87,78,63。求这个学生的分数,下面是这棵树的结构图(画的比较丑):

 

用组合模式就可以很好的解决,下面是代码:

//Component.java

package com.che.pattern.composite;

//抽象构建对象

public interface Component {
 public Component getComponent();
 public double calcScore();
}
 

//Composite.java

package com.che.pattern.composite;

import java.util.ArrayList;

import java.util.List;
//树枝构建对象
public class Composite implements Component {

 private List<Component> componentsList = new ArrayList<Component>();

 private double weight;
 
 public Composite(double weight){
  this.weight = weight;
 }
 
 @Override
 public Component getComponent() {
  return this;
 }

 @Override

 public double calcScore(){
  double total = 0;
  for(Component tmp : componentsList){
   total += tmp.calcScore();
  }
  return total * weight;
 }

 public void add(Component component){

  componentsList.add(component);
 }
 
 public void remove(Component component){
  componentsList.remove(component);
 }
 
 public List<Component> getChildrens(){
  return componentsList;
 }
}
 

//Leaf.java

package com.che.pattern.composite;

//树叶构建对象

public class Leaf implements Component {
 private double score;
 
 public Leaf(double score){
  this.score = score;
 }
 
 @Override
 public Component getComponent() {
  return this;
 }

 @Override

 public double calcScore() {
  return this.score;
 }
}

 

//Test.java

package com.che.pattern.composite;

public class Test {

 

 public static void main(String[] args) {
  Composite root = new Composite(1);
  
  Composite A = new Composite(0.3);
  Composite B = new Composite(0.4);
  Composite C = new Composite(0.3);
  
  Composite a1 = new Composite(0.5);
  a1.add(new Leaf(80));
  Composite a2 = new Composite(0.5);
  a2.add(new Leaf(70));
  A.add(a1);
  A.add(a2);
  
  Composite b1 = new Composite(0.3);
  b1.add(new Leaf(95));
  Composite b2 = new Composite(0.7);
  b2.add(new Leaf(87));
  B.add(b1);
  B.add(b2);
  
  Composite c1 = new Composite(0.4);
  c1.add(new Leaf(78));
  Composite c2 = new Composite(0.6);
  c2.add(new Leaf(63));
  C.add(c1);
  C.add(c2);
  
  root.add(A);
  root.add(B);
  root.add(C);
  
  System.out.println(root.calcScore());
 }
}

//打印结果

78.96000000000001

当然结果没有格式化,会稍有小数位的误差。

总结:这种实现方式只是组合模式的安全式的实现,而且是自上向下的,即父节点能够得到子节点的引用,该程序只要稍微改改就能让它也具有自下向上的功能,即子节点也可以得到父节点的引用,只要在Componet中加一个getParent,setParent方法,然后树枝添加树叶的时候,树叶调用setParent(this)即可,树枝删除树叶的时候,树叶调用setParent(null)即可。