如何设计实现支持递归遍历的文件系统(附代码实现)

407 阅读2分钟

基本概念

设计一个支持递归遍历的文件系统可以使用组合模式(Composite Pattern)。组合模式允许将对象组合成树形结构来表示“部分-整体”的层次结构。

在这种模式下,客户端(调用方)可以统一对待单个对象和组合对象。 组合模式跟面向对象设计中的“组合关系(通过组合来组装两个类)”,完全是两码事。这里讲的“组合模式”,主要是用来处理树形结构数据。

实现思路

  1. 定义组件接口

    • 创建一个接口 FileSystemComponent,包含基本的方法(如 display)。
  2. 实现文件类

    • 创建 File 类,表示文件,包含文件名,并实现 display 方法。
  3. 实现文件夹类

    • 创建 Folder 类,表示文件夹,可以包含多个文件和子文件夹,提供添加和移除子组件的方法,并实现 display 方法以递归显示结构。
  4. 构建文件系统

    • 使用这两个类构建文件系统的层次结构,并通过 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

总结

通过组合模式,可以轻松地构建和遍历一个复杂的文件系统结构。每个文件和文件夹都实现了相同的接口,使得它们可以被统一处理。这种设计不仅清晰易懂,还具有良好的扩展性,便于未来添加更多功能(如删除文件、搜索等)。