设计模式之组合模式(Java实现)
Composite(组合)
一、意图
将对象组合成树型结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。
二、结构
组合模式的结构如图7.33所示。 其中: • Component为组合中的对象声明接口;在适当情况下实现所有类共有接口的默认行为; 声明一个接口用于访问和管理Component的子组件;(可选)在递归结构中定义一个接口,用于访问一个父组件,并在合适的情况下实现它。 • Leaf在组合中表示叶结点对象,叶结点没有子结点;在组合中定义图元对象的行为。 • Composite定义有子组件的那些组件的行为;存储子组件;在Component接口中实现与子组件有关的操作。 • Client通过Component接口操纵组合组件的对象。
三、适用性
Composite模式适用于: • 想表示对象的部分-整体层次结构。 • 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
四、实现
现欲构造一文件/目录树,采用组合(Composite)设计模式来设计,得到的类图如下图 所示: 首先 创建抽象文件类。
abstract class AbstractFile {
protected String name; //文件或目录名称
public void printName() {
System.out.println(name);
}
//给一个目录增加子目录或文件
public abstract boolean addChild(AbstractFile file);
//删除一个目录的子目录或文件
public abstract boolean removeChild(AbstractFile file);
//获得一个目录的子目录或文件
public abstract List<AbstractFile> getChildren();
}
然后 创建文件类和文件夹类分别继承抽象文件类。
class File extends AbstractFile {
public File(String name) {
this.name = name;
}
public boolean addChild(AbstractFile file) {
return false;
}
public boolean removeChild(AbstractFile file) {
return false;
}
public List<AbstractFile> getChildren() {
return null ;
}
}
class Folder extends AbstractFile {
private List<AbstractFile> childList; //存储子目录或文件
public Folder(String name) {
this.name = name;
this.childList = new ArrayList<AbstractFile>();
}
public boolean addChild(AbstractFile file) {
return childList.add(file);
}
public boolean removeChild(AbstractFile file) {
return childList.remove(file);
}
public List <AbstractFile> getChildren() {
return childList ;
}
}
最后 测试一下。
public class Composite {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 创造一个树形的文件/目录结构
AbstractFile rootFolder = new Folder("c:\");
AbstractFile compositeFolder = new Folder("composite");
AbstractFile windowsFolder = new Folder("windows");
AbstractFile file = new File("TestComposite.java");
rootFolder.addChild(compositeFolder);
rootFolder.addChild(windowsFolder);
compositeFolder.addChild(file);
// 打印目录文件数
printTree(rootFolder);
}
private static void printTree(AbstractFile ifile) {
ifile.printName();
List<AbstractFile> children = ifile.getChildren();
if (children == null) return;
for (AbstractFile file : children) {
printTree(file) ;
}
}
}
运行结果:
