#include <iostream>
#include <memory>
#include <vector>
#include <string>
#include <algorithm> // for std::find
#include <stdexcept>

// Abstract Component: File System Node
class FileSystemNode {
public:
    virtual ~FileSystemNode() = default;
    virtual void show(int depth = 0) const = 0;
    virtual int getSize() const = 0;

    // Transparent Composite Pattern: Declare add/remove in abstract class, leaf nodes don't support by default
    virtual void add(std::shared_ptr<FileSystemNode> child) {
        throw std::logic_error("Cannot add to a leaf node.");
    }
    virtual void remove(std::shared_ptr<FileSystemNode> child) {
        throw std::logic_error("Cannot remove from a leaf node.");
    }
};

// Leaf Component: File
class File : public FileSystemNode {
    std::string name_;
    int size_; // File size (KB)
public:
    File(const std::string& name, int size) : name_(name), size_(size) {}

    void show(int depth = 0) const override {
        std::cout << std::string(depth, '-')
                  << "File: " << name_ << " (" << size_ << "KB)" << std::endl;
    }

    int getSize() const override {
        return size_;
    }
};

// Composite Component: Directory
class Directory : public FileSystemNode {
    std::string name_;
    std::vector<std::shared_ptr<FileSystemNode>> children_;
public:
    Directory(const std::string& name) : name_(name) {}

    void add(std::shared_ptr<FileSystemNode> child) override {
        children_.push_back(child);
    }

    void remove(std::shared_ptr<FileSystemNode> child) override {
        auto it = std::find(children_.begin(), children_.end(), child);
        if (it != children_.end()) {
            children_.erase(it);
        }
    }

    void show(int depth = 0) const override {
        std::cout << std::string(depth, '-')
                  << "Directory: " << name_ << " (total: " << getSize() << "KB)" << std::endl;
        for (const auto& child : children_) {
            child->show(depth + 2); // 缩进子节点
        }
    }

    int getSize() const override {
        int total = 0;
        for (const auto& child : children_) {
            total += child->getSize();
        }
        return total;
    }
};

int main() {
    // 构建文件系统树
    auto root = std::make_shared<Directory>("root");
    root->add(std::make_shared<File>("file1.txt", 100));
    root->add(std::make_shared<File>("file2.txt", 200));

    auto subDir = std::make_shared<Directory>("subdir");
    subDir->add(std::make_shared<File>("file3.txt", 300));
    subDir->add(std::make_shared<File>("file4.txt", 400));

    auto nestedDir = std::make_shared<Directory>("nested");
    nestedDir->add(std::make_shared<File>("file5.txt", 50));
    subDir->add(nestedDir);

    root->add(subDir);

    // 统一接口调用:展示结构并计算总大小
    std::cout << "File system structure:\n";
    root->show();

    std::cout << "\nTotal size of root: " << root->getSize() << "KB" << std::endl;

    // 展示对叶子节点调用 add 会抛出异常(透明组合的约束)
    try {
        auto file = std::make_shared<File>("orphan.txt", 10);
        file->add(std::make_shared<File>("child.txt", 5));
    } catch (const std::exception& e) {
        std::cout << "Exception caught: " << e.what() << std::endl;
    }

    return 0;
}

results matching ""

    No results matching ""