容器与内容的一致性
1.基本介绍
该模式用于创造出像文件夹和文件这样的结构,使容器与内容具有一致性,创造出递归模式,就如同文件夹中可以存入文件,也可以存入文件夹,而查找的时候,都可以获得其条目名。
2.具体实现
类的一览表
类图
Entry类:
是一个制定规则的抽象类,定义了共有的方法.
/**
* @author Jay
* @date 2019/6/6 23:11
* @description
*/
public abstract class Entry {
public abstract String getName();
public abstract int getSize();
/**
* 子类去调用此方法时会抛出异常,父类也可以不规定此方法,文件夹类独有方法,又构成组合关系.
* @param entry
* @return
* @throws FileTreatmentException
*/
public Entry add(Entry entry) throws FileTreatmentException {
throw new FileTreatmentException();
}
/**
* 重载方法,这样可以区别出第一次,也可以不必在父类中写,子类中自己判断输出结构.
*/
public void printList() {
// 显示条目
printList("");
}
/**
* 为一览加前缀
* @param prefix
*/
protected abstract void printList(String prefix);
@Override
public String toString() {
return getName() + "(" + getSize() + ")";
}
}
File类
/**
* @author Jay
* @date 2019/6/6 23:15
* @description 普通文件类
*/
public class File extends Entry {
private String name;
private int size;
public File(String name, int size) {
super();
this.name = name;
this.size = size;
}
@Override
public String getName() {
return name;
}
@Override
public int getSize() {
return size;
}
@Override
protected void printList(String prefix) {
System.out.println(prefix + "/" + this);
}
}
Directory类
/**
* @author Jay
* @date 2019/6/6 23:15
* @description 文件夹类
*/
public class Directory extends Entry {
private String name;
/**
* 只有文件夹才是数组结构,文件只是其中的元素,所以类型为directory
* 而其中元素可以是文件,也可以是文件夹,所以泛型为父类泛型
* 多个数组的套嵌结构,形成了文件树的结构形式.
*/
private ArrayList<Entry> directory = new ArrayList<Entry>();
public Directory(String name) {
super();
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public int getSize() { // 获取大小
int size = 0;
Iterator it = directory.iterator();
while (it.hasNext()) {
Entry entry = (Entry) it.next();
// 获取长度
size += entry.getSize();
}
return size;
}
/**
* 重写了父类的添加方法.
*/
@Override
public Entry add(Entry entry) {
directory.add(entry);
return this;
}
@Override
protected void printList(String prefix) { // 目录条目一览
System.out.println(prefix + "/" + this);
Iterator it = directory.iterator();
while (it.hasNext()) {
Entry entry = (Entry) it.next();
// 递归调用,父类接收,判断向下转型,调用各自对应方法.
entry.printList(prefix + "/" + name);
}
}
}
Main
测试类
/**
* @author Jay
* @date 2019/6/6 23:17
* @description
*/
public class Main {
public static void main(String[] args) {
Directory dirRoot = new Directory("root");
Directory dirUser = new Directory("user");
Directory dirBin = new Directory("bin");
Directory dirTmp = new Directory("tmp");
dirRoot.add(dirBin);
dirRoot.add(dirUser);
dirRoot.add(dirTmp);
dirBin.add(new File("bin1", 1024));
Directory dirAdmin= new Directory("admin");
dirUser.add(dirAdmin);
dirUser.add(new File("admin1", 1024));
dirRoot.printList();
}
}
最终创建如同上图的文件树结构.
3.角色分析
Leaf(树叶)
表示内容,如同文件.
Composite(复合物)
表示容器的角色,可以放入leaf和compostie,如同文件夹.
Compontent
上述俩者的父类,定义共同的功能.
4.思考
该模式可以将容器与内容一致性.所以称为多个和单个的一致性,即将多个对象结合在一起,当作同一个对象处理.
Add方法的设计处理:
- 在父类中,文件夹类重写,文件类调用会报错
- 在父类中,不做任何行为,这样文件类调用不会发生任何变化
- 可以在父类中声明,由子类具体实现.
- 只定义在文件夹类中.这样向下转型就需要进行类型判断.
此结构运用递归调用,遍历其中所有元素,所以,树结构都适用此模式.