基本概念
设计一个支持递归遍历的文件系统可以使用组合模式(Composite Pattern)。组合模式允许将对象组合成树形结构来表示“部分-整体”的层次结构。
在这种模式下,客户端(调用方)可以统一对待单个对象和组合对象。 组合模式跟面向对象设计中的“组合关系(通过组合来组装两个类)”,完全是两码事。这里讲的“组合模式”,主要是用来处理树形结构数据。
实现思路
-
定义组件接口:
- 创建一个接口
FileSystemComponent
,包含基本的方法(如display
)。
- 创建一个接口
-
实现文件类:
- 创建
File
类,表示文件,包含文件名,并实现display
方法。
- 创建
-
实现文件夹类:
- 创建
Folder
类,表示文件夹,可以包含多个文件和子文件夹,提供添加和移除子组件的方法,并实现display
方法以递归显示结构。
- 创建
-
构建文件系统:
- 使用这两个类构建文件系统的层次结构,并通过
display
方法递归遍历整个结构。
- 使用这两个类构建文件系统的层次结构,并通过
Dart代码实现:
// 定义文件系统组件接口
abstract class FileSystemComponent {
String get name;
void display(String indent);
}
// 文件类实现
class File implements FileSystemComponent {
@override
String name;
File(this.name);
@override
void display(String indent) {
print('$indent$name');
}
}
// 文件夹类实现
class Folder implements FileSystemComponent {
@override
String name;
List<FileSystemComponent> children = [];
Folder(this.name);
void add(FileSystemComponent component) {
children.add(component);
}
void remove(FileSystemComponent component) {
children.removeWhere((child) => child.name == component.name);
}
@override
void display(String indent) {
print('$indent$name/');
String newIndent = '$indent ';
for (var child in children) {
child.display(newIndent);
}
}
}
// 主函数,构建文件系统并测试
void main() {
var rootFolder = Folder('Root');
var subFolder1 = Folder('SubFolder1');
var subFolder2 = Folder('SubFolder2');
var file1 = File('File1.txt');
var file2 = File('File2.txt');
var file3 = File('File3.txt');
subFolder1.add(file1);
subFolder1.add(file2);
subFolder2.add(file3);
rootFolder.add(subFolder1);
rootFolder.add(subFolder2);
// 递归遍历并显示结构
rootFolder.display('');
}
Swift代码实现
import Foundation
// 定义文件系统组件协议
protocol FileSystemComponent {
var name: String { get }
func display(indent: String)
}
// 文件类实现
class File: FileSystemComponent {
var name: String
init(name: String) {
self.name = name
}
func display(indent: String) {
print("\(indent)\(name)")
}
}
// 文件夹类实现
class Folder: FileSystemComponent {
var name: String
private var children: [FileSystemComponent] = []
init(name: String) {
self.name = name
}
func add(component: FileSystemComponent) {
children.append(component)
}
func remove(component: FileSystemComponent) {
children.removeAll { $0.name == component.name }
}
func display(indent: String) {
print("\(indent)\(name)/")
let newIndent = indent + " "
for child in children {
child.display(indent: newIndent)
}
}
}
// 构建文件系统并测试
func test() {
let rootFolder = Folder(name: "Root")
let subFolder1 = Folder(name: "SubFolder1")
let subFolder2 = Folder(name: "SubFolder2")
let file1 = File(name: "File1.txt")
let file2 = File(name: "File2.txt")
let file3 = File(name: "File3.txt")
subFolder1.add(component: file1)
subFolder1.add(component: file2)
subFolder2.add(component: file3)
rootFolder.add(component: subFolder1)
rootFolder.add(component: subFolder2)
// 递归遍历并显示结构
rootFolder.display(indent: "")
}
输出结果
Root/
SubFolder1/
File1.txt
File2.txt
SubFolder2/
File3.txt
总结
通过组合模式,可以轻松地构建和遍历一个复杂的文件系统结构。每个文件和文件夹都实现了相同的接口,使得它们可以被统一处理。这种设计不仅清晰易懂,还具有良好的扩展性,便于未来添加更多功能(如删除文件、搜索等)。