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