FileManager.hpp Шаблон проектирования: Стратегия
Добавлено: 06 авг 2025, 17:35
Код: Выделить всё
#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;
}
*/