读书笔记 仅供参考
简述
Composite 是混合物,复合物的意思。类似与“文件夹”的概念,文件夹当中可以放文件也可以放文件夹,文件夹形成了一种容器结构、递归结构,有时文件和文件夹当作同一种对象看待。
Composite 模式就是创造这样结构的模式。能够使容器与内容具有一致性,创造出递归结构。
UML 和角色
Leaf
表示“内容”的角色,在该角色中不能放入其他对象,就像一个文件
Composite
表示容器的角色,可以在其中放入 Leaf 和 Composite 角色,类似文件夹
Component
Leaf 和 Composite 的父类
Client
使用 Composite 模式的角色
UML
例子
例程是一个文件夹和文件的程序,文件夹可以加入文件夹和文件,并且可以输出文件夹下面的所以文件和文件夹名称和大小。
UML
//角色中的 Component,表示目录条目的抽象类
public abstract class Entry {
public abstract String getName();
public abstract int getSize();
public Entry add(Entry entry) throws FileTreatmentException{
throw new FileTreatmentException();
}
//显示目录条目一览
public void printList() {
printList("");
}
//为一览加上前缀
protected abstract void printList(String prefix);
@Override
public String toString() {
return getName() + " (" + getSize() + ")";
}
}
//Leaf 角色
public class File extends Entry{
//文件名
private String name;
//文件大小
private int size;
public File(String name, int size) {
this.name = name;
this.size = size;
}
public void setName(String name) {
this.name = name;
}
public void setSize(int size) {
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);
}
}
//防止对文件进行 add操作
public class FileTreatmentException extends RuntimeException{
public FileTreatmentException() {
}
public FileTreatmentException(String msg) {
super(msg);
}
}
// Composite 角色,表示文件夹
public class Directory extends Entry {
//文件夹名
private String name;
//文件、文件夹列表
private List<Entry> directory = new ArrayList<>();
public Directory(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public int getSize() {
int size = 0;
Iterator<Entry> it = directory.iterator();
while (it.hasNext()) {
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<Entry> it = directory.iterator();
while (it.hasNext()) {
Entry entry = it.next();
entry.printList(prefix + "/" + name);
}
}
}
public class Main {
public static void main(String[] args) {
try {
System.out.println("Make root entries");
Directory rootDir = new Directory("root");
Directory binDir = new Directory("bin");
Directory tmpDir = new Directory("tmp");
Directory usrDir = new Directory("usr");
rootDir.add(binDir);
rootDir.add(tmpDir);
rootDir.add(usrDir);
binDir.add(new File("vi", 10000));
binDir.add(new File("latex", 20000));
rootDir.printList();
System.out.println();
System.out.println("Making user entries...");
Directory yuki = new Directory("yuki");
Directory hanako = new Directory("hanako");
Directory tomura = new Directory("tomura");
usrDir.add(yuki);
usrDir.add(hanako);
usrDir.add(tomura);
yuki.add(new File("diary.html", 100));
yuki.add(new File("Composite.java", 200));
hanako.add(new File("memo.txt", 300));
tomura.add(new File("game.doc", 400));
tomura.add(new File("junk.doc", 500));
rootDir.printList();
}catch (FileTreatmentException e) {
e.printStackTrace();
}
}
}
结果
多个和单个的一致性
使用 Composite 模式可以使容器与内容具有一致性,也可以称其为多个和单个的一致性,即将多个对象结合在一起,当作一个对象进行处理。