设计模式--------组合模式
介绍组合模式的三大问题
- 什么是组合模式?
- 组合模式有什么好处?
采用一个案例来说明问题
- 现有一个磁盘,磁盘中有文件夹也有文件,没有指定的文件夹层数,一个目录下有文件也可能有文件夹,采用一个好的方式,可以简单的遍历所有的文件,文件夹,以及可以按照指定的要求筛选
常见思路
- 创建一个文件夹类
- List<文件夹>: 存储文件夹下的文件夹
- List<文件>: 存储文件夹下的文件
- print(): 递归输出文件夹中的文件信息
- 创建一个文件类
- name: 文件名
- description: 描述
Folder
public class Folder {
public Folder() {
folders = new ArrayList<>();
files = new ArrayList<>();
}
List<Folder> folders;
List<File> files;
public void print() {
for (int i = 0; i < files.size(); i++) {
files.get(i).print();
}
for (int i = 0; i < folders.size(); i++) {
folders.get(i).print();
}
}
public void addFile(File file) {
files.add(file);
}
public void addFolder(Folder folder) {
folders.add(folder);
}
}
File
public class File {
String name;
String description;
public File(String name, String description) {
this.name = name;
this.description = description;
}
public void print() {
System.out.println("name: " + name + " description: " + description);
}
}
Reader
public class Reader {
Folder folder;
public Reader(Folder folder) {
this.folder = folder;
}
public void read() {
folder.print();
}
}
Main
public class Main {
public static void main(String[] args) throws Exception {
Folder folder = new Folder();
folder.addFile(new File("1", "1"));
folder.addFile(new File("2", "2"));
folder.addFile(new File("3", "3"));
folder.addFile(new File("4", "4"));
Folder folder2 = new Folder();
folder2.addFile(new File("5", "5"));
folder2.addFile(new File("6", "6"));
folder2.addFile(new File("7", "7"));
folder2.addFile(new File("8", "8"));
folder.addFolder(folder2);
Reader reader = new Reader(folder);
reader.read();
}
}
/// out
name: 1 description: 1
name: 2 description: 2
name: 3 description: 3
name: 4 description: 4
name: 5 description: 5
name: 6 description: 6
name: 7 description: 7
name: 8 description: 8
有什么问题?
- 当添加文件和文件夹,以及读取文件和文件夹都是分别区分对待的
- 有没有一种办法,可以让他们一视同仁
什么是组合模式
- 允许将对象组合成树形结构来表现 整体/部分 层次结构,组合能让客户以一致的方式处理个别对象以及对象组合
使用组合模式改写代码
- 创建一个共同的接口,让文件和文件夹实现,以便能够使用统一的方法处理文件和文件夹,对于有一些接口文件夹或文件可能用不到,可以采用默认抛出异常的方式,各自实现自己需要的接口
Component
public abstract class Component {
public void add(Component component) {
throw new UnsupportedOperationException();
}
public String getName() {
throw new UnsupportedOperationException();
}
public String getDescription() {
throw new UnsupportedOperationException();
}
public void remove() {
throw new UnsupportedOperationException();
}
public void print() {
throw new UnsupportedOperationException();
}
}
File
public class File extends Component {
String name;
String description;
public File(String name, String description) {
this.name = name;
this.description = description;
}
@Override
public String getName() {
return name;
}
@Override
public String getDescription() {
return description;
}
@Override
public void print() {
System.out.println("name: " + name + " description: " + description);
}
}
Folder
public class Folder extends Component {
List<Component> files;
public Folder() {
files = new ArrayList<>();
}
@Override
public void add(Component component) {
files.add(component);
}
@Override
public void print() {
Iterator<Component> iterator = files.iterator();
while(iterator.hasNext()) {
Component component = iterator.next();
component.print();
}
}
}
Reader
public class Reader {
Component component;
public Reader(Component component) {
this.component = component;
}
public void read() {
component.print();
}
}
Main
public class Main {
public static void main(String[] args) throws Exception {
Component folder = new Folder();
folder.add(new File("1", "1"));
folder.add(new File("2", "2"));
folder.add(new File("3", "3"));
folder.add(new File("4", "4"));
Component folder2 = new Folder();
folder2.add(new File("5", "5"));
folder2.add(new File("6", "6"));
folder2.add(new File("7", "7"));
folder2.add(new File("8", "8"));
folder.add(folder2);
Reader reader = new Reader(folder);
reader.read();
}
}
// out
name: 1 description: 1
name: 2 description: 2
name: 3 description: 3
name: 4 description: 4
name: 5 description: 5
name: 6 description: 6
name: 7 description: 7
name: 8 description: 8
组合模式有什么好处?
- 可以看到因为采用了统一的接口所以客户无需关心对象类别
END
不慕招式,勤修内功