组合模式
定义:将对象组合成树形结构以表示部分整体得层次结构。组合模式使用户对单一对象和组合对象使用具有一致性。
使用场景:希望用户忽略组合对象和单个对象的不同,统一的使用组合结构中的所有对象。如文件、文件夹的管理。
有两种方式:
- 透明方式:
由于抽象构件声明了所有子类中的全部方法,所以客户端无须区别树叶对象和树枝对象,对客户端来说是透明的。但缺点是树叶构件本来没有add(),remove()等方法,却要实现他们(空实现、抛异常),会带来安全问题。
2. 安全方式
这种方式中,将管理子构件的方法移到树枝构件中,这样子构件和抽象构件中就不需要写这些冗余的方法。但是客户端调用的时候就要知道树叶构件和树枝构件的存在,失去了透明性。
代码示例:
public interface IFile {
void delete();
String getName();
void createNewFile(String name);
void deleteFile(String name);
}
public class File implements IFile{
private String name;
private IFile folder;
public File(String name,IFile folder) {
super();
this.name = name;
this.folder = folder;
}
public String getName() {
return name;
}
public void delete() {
folder.deleteFile(name);
System.out.println("---删除[" + name + "]---");
}
//文件不支持创建新文件
public void createNewFile(String name) {
throw new UnsupportedOperationException();
}
//文件不支持删除文件
public void deleteFile(String name) {
throw new UnsupportedOperationException();
}
//文件不支持获取下面的文件列表
public IFile getIFile(int index) {
throw new UnsupportedOperationException();
}
}
public class Folder implements IFile {
private String name;
private IFile folder;
private List<IFile> files;
public Folder(String name, IFile folder) {
this.name = name;
this.folder = folder;
files=new ArrayList<>();
}
@Override
public void delete() {
List<IFile> copy = new ArrayList<IFile>(files);
System.out.println("------------删除子文件-------------");
for (IFile file:copy){
file.delete();
}
if (folder != null) {
folder.deleteFile(name);
}
System.out.println("---删除[" + name + "]---");
}
@Override
public String getName() {
return name;
}
@Override
public void createNewFile(String name) {
if (name.contains(".")) {
files.add(new File(name,this));
}else {
files.add(new Folder(name,this));
}
}
@Override
public void deleteFile(String name) {
for (IFile file : files) {
if (file.getName().equals(name)) {
files.remove(file);
break;
}
}
}
}