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)即可。