Composite 模式
能够使容器与内容具有一致性,创造出递归结构的模式就是Composite模式。
示例程序类图
示例程序
Entry
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() + ")";
}
}
File
public class File extends Entry {
private String name
;
private int size
;
public File(String name
, int size
) {
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
import java
.util
.Iterator
;
import java
.util
.ArrayList
;
public class Directory extends Entry {
private String name
;
private ArrayList directory
= new ArrayList();
public Directory(String name
) {
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
);
}
}
}
FileTreatmentException
public class FileTreatmentException extends RuntimeException {
public FileTreatmentException() {
}
public FileTreatmentException(String msg
) {
super(msg
);
}
}
Main
public class Main {
public static void main(String
[] args
) {
try {
System
.out
.println("Making 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.tex", 300));
tomura
.add(new File("game.doc", 400));
tomura
.add(new File("junk.mail", 500));
rootdir
.printList();
} catch (FileTreatmentException e
) {
e
.printStackTrace();
}
}
}
Composite 模式中的登场角色
1.Leaf(树叶)
表示“内容”的角色。在该角色中不能放入其他对象。在示例程序中,由File类扮演此角色。
2.Composite(复合物)
表示容器的角色。可以在其中放入Leaf角色和Composite角色。在示例程序中,由Directory类扮演此角色。
3.Component
使Leaf角色和Composite角色具有一致性的角色。Component角色是Leaf角色和Composite角色的父类。在示例程序中,由Entry类扮演此角色。
4.Client
使用Composite模式的角色。在示例程序中,由Main类扮演此角色。
通用类图
注意点
使用Composite模式可以使容器与内容具有一致性,也可以称其为多个和单个的一致性,即将多个对象结合在一起,当作一个对象进行处理。