组合模式
一、概念
将对象以树形结构组织起来,以达成“部分-整体”的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。
树的结构->组合设计模式
二、使用场景
需要表示一个对象整体或部分层次
让客户能够忽略不同对象层次的变化
三、UML结构
四、代码示例
File:
public abstract class File {
private String name;
public File(String name){
this.name = name;
}
//操作方法
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public abstract void watch();
//组合方法
public void add(File file){
throw new UnsupportedOperationException();
}
//组合方法
public void remove(File file){
throw new UnsupportedOperationException();
}
//组合方法
public File getChild(int position){
throw new UnsupportedOperationException();
}
}
Folder:
public class Folder extends File{
private List<File> fileList;
public Folder(String name) {
super(name);
fileList = new ArrayList<>();
}
@Override
public void watch() {
StringBuffer fileName = new StringBuffer();
for (File file : fileList) {
fileName.append(file.getName()+":");
}
System.out.printf("组合模式","这是一个叫"+getName()+"文件夹,包含"+fileList.size()+"个文件,分别是:"+fileName);
}
@Override
public void add(File file) {
fileList.add(file);
}
@Override
public void remove(File file) {
fileList.remove(file);
}
@Override
public File getChild(int position) {
return fileList.get(position);
}
}
TextFile:
public class TextFile extends File{
public TextFile(String name) {
super(name);
}
@Override
public void watch() {
System.out.printf("组合模式","这是一个叫"+getName()+"文本文件");
}
}
TestComposite:
public class TestComposite {
public static void main(String[] args) {
TextFile textFileA = new TextFile("a.txt");
TextFile textFileB = new TextFile("b.txt");
TextFile textFileC = new TextFile("c.txt");
textFileA.watch();
//调用会抛抽象接口中的异常
//textFileA.add(textFileB);
Folder folder = new Folder("设计模式");
folder.add(textFileA);
folder.add(textFileB);
folder.add(textFileC);
folder.watch();
folder.getChild(1).watch();
}
}
其中,folder和textFile都是抽象类File的结点,只关心File的改变,不去关心folder和textFile的变化,最后通过直接访问file来实现。
五、组合模式的优点
- 高层模块调用简单
- 节点自由增加
缺点:
- 不容易控制数据结构的类型
- 使用了继承,想要增加新的行为较为困难