其实我一开始念组合模式的时候,差点和建造者模式混淆,
我以为就是多个子部分组合到一起,然后就是差不多组合模式。
然后我发现我的第一感觉是错误的。
先看个类图吧:
类图十分的简单。
并且第一眼看去,Leaf和Composite几乎一模一样,为什么这就是组合模式的类图呢?
可以通过一个情景来加深印象:
假设一个公司让给做员工OA系统,包括总部的系统,以及众多分公司的系统,
并且公司的组织架构和部门的组着架构也有大部分相同,部门也要一个系统。
一方面,如果只做一个总系统,全部人一起使用的话,那可能会有很多判断语句进行不同的角色判定,
另一方面,如果每个部门都做一套各自的系统的话,又会任务量太大而不划算。
当然这个时候就可以用组合模式来解决相关的问题了。
将相同的部分抽象出来,形成一套规范。
这个时候再来理解上面的类图,
先以树叶(Leaf)和躯干(Compsite)为例看代码吧:
Component类:
package com.blog.anla.Composite;
/**
* Component为组合中对象声明接口,在适当情况下,实现
* 所有类共有接口的默认行为。声明一个接口用于访问和管理
* Component的子部件。
* @author U-ANLA
*
*/
public abstract class Component {
protected String name;
public Component(String name){
this.name = name;
}
public abstract void Add(Component c);
public abstract void remove(Component c);
public abstract void display(int depth);
}
Leaf类:
package com.blog.anla.Composite;
/**
* 叶子组件,虽然有add和remove方法,
* 但是只是个头,实际无方法体,可以理解为没有
* 这项操作。
* @author U-ANLA
*
*/
public class Leaf extends Component{
public Leaf(String name) {
super(name);
}
@Override
public void Add(Component c) {
System.out.println("叶子无法添加叶子");
}
@Override
public void remove(Component c) {
System.out.println("叶子无法删除叶子");
}
@Override
public void display(int depth) {
System.out.println(new String("-depth")+name);
}
}
Composite类:
package com.blog.anla.Composite;
import java.util.ArrayList;
import java.util.List;
/**
* Composite的定义有行为,可以增加或者删除下面的节点。
* @author U-ANLA
*
*/
public class Composite extends Component{
private List<Component> children = new ArrayList<Component>();
public Composite(String name) {
super(name);
}
@Override
public void Add(Component c) {
children.add(c);
}
@Override
public void remove(Component c) {
children.remove(c);
}
@Override
public void display(int depth) {
System.out.println("-"+depth+name);
for(int i = 0;i < children.size();i++){
children.get(i).display(depth+2);
}
}
}
由上面具体代码可以看到,虽然Leaf和Composite两个类在类结构上几乎一样,但是
Leaf类中大部分方法都没有实现,而Composite中却有具体的实现。
这就是组合模式,类似于分公司和部门的关系。
组合模式就是让客户可以一直的使用组合结构和单个对象。
相信大家也跟我一样懂了建造者模式和组合模式的区别了吧哈哈哈
赠人玫瑰手留余香(oo)
设计模式相关代码以及类图的整个项目都托管到了github上,包括各个模式的示例
代码以及类图,类图则用的visio绘制,整个visio文件也在该项目上,这里贴上地址:
https://github.com/anLA7856/design
如果觉得有帮助,start一下呗~我会非常开心的