1.组合模式的定义及使用场景
组合模式也称为部分整体模式,结构型设计模式之一,组合模式比较简单,它将一组相似的对象看作一个对象处理,并根据一个树状结构来组合对象,然后提供一个统一的方法去访问相应的对象,以此忽略掉对象与对象集合之间的差别。生活中一个比较经典的例子就是组织结构的树状图。
定义:
将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性
使用场景:
维护和展示部分-整体关系的场景,如树形菜单、文件和文件夹管理
从一个整体中能够独立出部分模块或功能的场景
2. 组合模式的优缺点
2.1优点
组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让高层模块忽略了层次的差异,方便对整个层级结构进行控制
高层模块可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了高层模块的代码
在组合模式中增加新的枝干构件和叶子构件都很方便,无需对现有类库进行任何修改
组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子对象和枝干对象的递归组合,可以形成复杂的树形结构,但对树形结构的控制却非常简单##2.2缺点在新增构件时不好对枝干中的构件类型进行限制,不能依赖类型系统来施加这些约束,因为在大多数情况下,他们都来自于相同的抽象层,此时,必须进行类型检查来实现,过程比较复杂
3.注意事项
组合模式有两种不同的实现:透明模式和安全模式(4点中为安全模式),透明模式是把用来组合使用的方法放到抽象类中,不管叶子对象还是树枝对象都有相同的结构。这种模式的缺点是通过判断getChildren的返回值确认是叶子节点还是树枝节点,如果处理不当,会在运行期出现问题,安全模式它是把树枝节点和叶子节点彻底分开,树枝节点单独拥有用来组合的方法。
4. 组合模式的实现方式
public abstract class Component {
public void doSomething() {
}
}```
public class Composite extends Component {
private ArrayList<Component> componentArrayList = new ArrayList<>();
public void add(Component component) {
componentArrayList.add(component);
}
public void remove(Component component) {
componentArrayList.remove(component);
}
public ArrayList<Component> getChildren() {
return this.componentArrayList;
}
@Override
public void doSomething() {
System.out.println("Composite do something");
}
}```
public class Leaf extends Component {
@Override
public void doSomething() {
System.out.println("Leaf do someThing");
}
}
public class Test {
public static void main(String args[]) {
//创建一个根节点
Composite root = new Composite();
root.doSomething();
//创建一个树枝构件
Composite barnch = new Composite();
//创建一个叶子节点
Leaf leaf = new Leaf();
//建立整体
root.add(barnch);
barnch.add(leaf);
//遍历
display(root);
}
public static void display(Composite composite) {
for (Component c : composite.getChildren()) {
if (c instanceof Leaf) {
c.doSomething();
} else {
display((Composite) c);
}
}
}
}```
**5. 组合模式在Android中的实际应用**
Android源码中关于组合模式有一个非常经典的实现,我们几乎每天都会使用到,那就是View和ViewGroup的嵌套组合。
![Paste_Image.png](http://upload-images.jianshu.io/upload_images/5423625-40336fff7e41f8e1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
这里省略了View和ViewGroup的一些方法,在Android的这个视图层级中,容器一定是ViewGroup,而且只有ViewGroup才能包含其他的View,例如Realyout能包含TextView、Button等,但反过来TextView不能包含Relayout,因为TextView直接继承了View,并不是一个容器,这里View的视图层级中使用的其实是一种安全的设计模式。
出处:http://huangjunbin.com/page/2/