Android设计模式-18-组合模式
2018-06-16 本文已影响53人
今阳说
1.定义
- 也叫部分整体模式
- 将对象组合成树形结构以表示 “部分-整体” 的层次结构,使得用户对单个对象和组合对象的使用具有一致性
2. 使用场景:
- 部分、整体场景,如树形菜单,文件、文件夹的管理等
3. 优缺点
- 优点:
- 清楚的定义分层次的复杂对象, 表示对象的全部或部分层次,让高层模块忽略了层次的差异,方便对整个层次结构进行控制
- 高层模块可以一致的使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了高层模块的代码
- 增加新的枝干构件和叶子构件都很方便,无需对现有类库进行更改,符合开闭原则
- 为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子对象和枝干对象的递归组合,可以形成复杂的树形结构,但对树形结构的控制却非常简单
- 缺点:
新增构件时不好对枝干中的构件类型进行限制,不能依赖类型系统来施加这些约束,因为大多数情况,它们都来自相同的抽象层,此时必须进行类型检查,实现过程较为复杂
4. Android源码中的应用:
组合模式在Android中最明显的应用就是View,ViewGroup及其子孙类(各种控件)所构成的UI体系;
5. 实例演示
以电脑中的文件和文件夹为例
- 首先创建一个文件系统中元素的基类,包含文件/文件夹的一些基本属性和操作他们的方法
public abstract class Dir {
//存储文件夹下的所有元素
protected List<Dir> mDirs = new ArrayList<>();
private String name;//当前文件或文件夹名
public Dir(String name) {
this.name = name;
}
//添加
public abstract void addDir(Dir dir);
//移除
public abstract void rmDir(Dir dir);
//清空
public abstract void clear();
//获取所有子元素
public abstract List<Dir> getFiles();
//获取当前文件名
public String getName() {
return name;
}
//输出文件夹目录结构
public abstract String print();
}
- 创建一个基类的实现--文件类
public class Folder extends Dir {
public Folder(String name) {
super(name);
}
@Override
public void addDir(Dir dir) {
mDirs.add(dir);
}
@Override
public void rmDir(Dir dir) {
mDirs.remove(dir);
}
@Override
public void clear() {
mDirs.clear();
}
@Override
public List<Dir> getFiles() {
return mDirs;
}
@Override
public String print() {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(getName() + ":(");
java.util.Iterator<Dir> iterator = mDirs.iterator();
while (iterator.hasNext()) {
Dir dir = iterator.next();
dir.print();
if (iterator.hasNext()) {
stringBuffer.append(",");
}
}
stringBuffer.append(")");
return stringBuffer.toString();
}
}
- 创建基类的另一种实现类--文件类
public class File extends Dir {
public File(String name) {
super(name);
}
@Override
public void addDir(Dir dir) {
throw new UnsupportedOperationException("文件对象不支持该操作");
}
@Override
public void rmDir(Dir dir) {
throw new UnsupportedOperationException("文件对象不支持该操作");
}
@Override
public void clear() {
throw new UnsupportedOperationException("文件对象不支持该操作");
}
@Override
public List<Dir> getFiles() {
throw new UnsupportedOperationException("文件对象不支持该操作");
}
@Override
public String print() {
return getName();
}
}
- 创建文件及文件夹实例,组合成文件系统
private void methodCompositePattern() {
//创建一个文件夹对象表示根目录
Dir diskD = new Folder("D");
//D下创建一个文件
diskD.addDir(new File("dog.png"));
//game目录
Dir dirGame = new Folder("game");
diskD.addDir(dirGame);
//music目录
Dir dirMusic = new Folder("music");
dirMusic.addDir(new File("红蔷薇.mp3"));
dirMusic.addDir(new File("后来.mp3"));
diskD.addDir(dirMusic);
//打印文件结构
LjyLogUtil.i(diskD.print());
}