FileManager.hpp Шаблон проектирования: Стратегия

Ответить
ya
^-^
Сообщения: 2674
Зарегистрирован: 16 дек 2021, 19:56

FileManager.hpp Шаблон проектирования: Стратегия

Сообщение ya »

Код: Выделить всё

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <unordered_map>
#include <memory>
#include <exception>

// Исключение для ошибок файла
class FileOpenException : public std::runtime_error {
public:
    explicit FileOpenException(const std::string& message)
        : std::runtime_error(message) {}
};

// Интерфейс замены стратегий
class SubstitutionStrategy {
public:
    virtual std::string substitute(const std::string& content, 
                                    const std::unordered_map<std::string, std::string>& substitutions) const = 0;
};

// Конкретная стратегия для замены в тексте
class TextSubstitution : public SubstitutionStrategy {
public:
    std::string substitute(const std::string& content, 
                           const std::unordered_map<std::string, std::string>& substitutions) const override {
        std::string result = content;
        for (const auto& pair : substitutions) {
            size_t pos = 0;
            while ((pos = result.find(pair.first, pos)) != std::string::npos) {
                result.replace(pos, pair.first.length(), pair.second);
                pos += pair.second.length();
            }
        }
        return result;
    }
};

// Класс FileManager с использованием стратегии замены
class FileManager {
public:
    FileManager(const std::string& filePath, 
                std::shared_ptr<SubstitutionStrategy> strategy)
        : filePath(filePath), strategy(strategy) {}

    std::string readFileWithSubstitutions(const std::unordered_map<std::string, std::string>& substitutions) const {
        std::ifstream file(filePath);
        if (!file) {
            //std::cerr << "Ошибка открытия файла: " << filePath << std::endl;
			throw FileOpenException("Ошибка открытия файла: " + filePath);
            return "";
        }

        std::stringstream buffer;
        buffer << file.rdbuf();
        std::string content = buffer.str();

        return strategy->substitute(content, substitutions);
    }

private:
    std::string filePath;
    std::shared_ptr<SubstitutionStrategy> strategy;
};

// Фабрика стратегий замены
class SubstitutionFactory {
public:
    enum class StrategyType { Text, Database }; // Добавьте другие типы по мере необходимости

    static std::shared_ptr<SubstitutionStrategy> createStrategy(StrategyType type) {
        switch (type) {
            case StrategyType::Text:
                return std::make_shared<TextSubstitution>();
            // Добавьте условия для других стратегий
            default:
                throw std::invalid_argument("Неизвестный тип стратегии замены");
        }
    }
};
/*
int main(int argc, char* argv[]) {
    // Проверка наличия аргумента
    if (argc < 2) {
        std::cerr << "Использование: " << argv[0] << " <путь_к_файлу>" << std::endl;
        return 1;
    }

    std::string filePath = argv[1]; // Получаем путь к файлу из аргумента

    // Переменные для замены
    std::unordered_map<std::string, std::string> substitutions = {
        {"{name}", "Alice"},
        {"{age}", "30"},
        {"{city}", "Moscow"}
    };

    // Используем фабрику для создания стратегии
    auto strategy = SubstitutionFactory::createStrategy(SubstitutionFactory::StrategyType::Text);

    // Создаем FileManager
    FileManager fileManager(filePath, strategy);
    std::string content = fileManager.readFileWithSubstitutions(substitutions);

    if (!content.empty()) {
        std::cout << "Содержимое файла:\n" << content << std::endl;
    }
	/////////////////////////////////////////////////////////////////////////////////

	// или такой вариант через обработку ошибки отрытия несуществующего файла в классе FileOpenException
	try {
		auto strategy = SubstitutionFactory::createStrategy(SubstitutionFactory::StrategyType::Text);
		FileManager manager("somefile.txt", strategy);
		auto result = manager.readFileWithSubstitutions(someSubstitutions);
		std::cout << result << std::endl;
	} catch (const FileOpenException& e) {
		std::cerr << "Произошла ошибка: " << e.what() << std::endl;
	}
	
    return 0;
}
*/
Ответить