模式的定义
组合模式(Composite Pattern)定义如下:
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly。
将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
组合模式有时叫做部分—整体模式,主要是描述部分与整体的关系。
模式的使用场景
- 部分-整体关系的场景,如树形菜单,文件和文件夹管理
- 从一个整体中能够独立出部分模块或功能的场景
UML类图
角色介绍
- Component 抽象构件角色
定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性
- Leaf 叶子组件
叶子对象,其下再也没有其他的分支,也就是最小的单位
- Composite 树枝构件
树枝对象,它的作用就是组合树枝节点和叶子节点形成一个树形结构
模式的简单实现
Component:
public abstract class Component {
//个体和整体都具有的共享
public void doSomething(){
//业务逻辑
System.out.print("Component-----doSomething()");
}
}
Leaf :
public class Leaf extends Component {
//可以覆写父类方法
/* (non-Javadoc)
* @see Component#doSomething()
*/
@Override
public void doSomething() {
// TODO Auto-generated method stub
super.doSomething();
System.out.print("Leaf-------doSomething()");
}
@Override
public String toString() {
// TODO Auto-generated method stub
return super.toString();
}
}
Composite :
public class Composite extends Component{
private ArrayList<Component> components = new ArrayList<Component>();
public void add(Component component){
components.add(component);
}
public void remove(Component component){
components.remove(component);
}
public ArrayList<Component> getChildren(){
return components;
}
}
Client:
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
//create a root
Composite root = new Composite();
root.doSomething();
//create a branch
Composite branch = new Composite();
root.add(branch);
//create a leaf
Leaf leaf1 = new Leaf();
root.add(leaf1);
//create a leaf
Leaf leaf2 = new Leaf();
root.add(leaf2);
Display(root);
}
private static void Display(Composite root) {
// TODO Auto-generated method stub
for(Component c:root.getChildren()){
if(c instanceof Leaf){
System.out.println();
System.out.print("leaf----"+c.toString());
}else {
System.out.println();
System.out.print("Composite----"+c.toString());
Display((Composite)c);
}
}
}
}
优点
- 高层模块调用简单
一棵树形机构中的所有节点都是Component,局部和整体对调用者来说没有任何区别,也就是说高层模块不关心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码
- 节点自由增加
使用组合模式后,增加一个树枝节点,树叶节点都很容易,只要找到父节点就可以非常容易扩展,符合开闭原则,对以后的维护非常有利。
缺点
组合模式有一个明显的缺点,看我们的场景类中的定义,提到树叶与树枝使用时的定义。直接使用了实现类。这在面向接口编程上是不恰当的,与依赖倒置原则总被。
注意事项
只要是树形结构,就要考虑使用组合模式,这个一定要记住。只要是要体现局部和整体的关系的时候,而且这种关系还可能比较深,考虑一下组合模式。
Android源码中的模式实现
UML类图
具体实现代码
View.java
public class View ....{
//此处省略无关代码...
}
ViewGroup.java
public abstract class ViewGroup extends View ...{
private View[] mChildren;
//增加子节点
public void addView(View child, int index) {
}
//增加子节点
public void addView(View child) {
addView(child, -1);
}
//删除子节点
public void removeView(View view) {
}
//查找子节点
public View getChildAt(int index) {
if (index < 0 || index >= mChildrenCount) {
return null;
}
return mChildren[index];
}
}
参考资料
(1).设计模式之禅—第21章 组合模式
(2)composite Pattern 组合模式
https://github.com/simple-android-framework/android_design_patterns_analysis/tree/master/composite/tiny-times