Ответ
Принцип открытости/закрытости (Open/Closed Principle, OCP) — второй принцип SOLID. Он утверждает, что программные сущности (классы, модули, функции) должны быть открыты для расширения, но закрыты для модификации.
- Закрыты для модификации: Стабильный, протестированный код не должен изменяться при добавлении новой функциональности, чтобы не рисковать внесением ошибок.
- Открыты для расширения: Новая функциональность добавляется путем создания новых сущностей (через наследование, композицию, шаблоны), которые расширяют поведение существующих.
Пример нарушения OCP в C++:
class Logger {
public:
void log(const std::string& message, const std::string& type) {
if (type == "FILE") {
// запись в файл
} else if (type == "CONSOLE") {
// вывод в консоль
}
// Добавление нового типа (например, "NETWORK") требует МОДИФИКАЦИИ этого класса!
}
};
Пример соблюдения OCP с использованием полиморфизма:
// Абстрактный базовый класс, закрытый для модификации
class ILogger {
public:
virtual ~ILogger() = default;
virtual void log(const std::string& message) = 0;
};
// Конкретные реализации, открытые для расширения
class FileLogger : public ILogger {
public:
void log(const std::string& message) override { /* запись в файл */ }
};
class ConsoleLogger : public ILogger {
public:
void log(const std::string& message) override { /* вывод в консоль */ }
};
// НОВЫЙ тип логгера можно добавить БЕЗ изменения существующего кода
class NetworkLogger : public ILogger {
public:
void log(const std::string& message) override { /* отправка по сети */ }
};
// Клиентский код работает с абстракцией
void process(ILogger& logger) {
logger.log("Operation completed");
}
Таким образом, для добавления нового способа логирования мы создаем новый класс, а не меняем старые, что снижает риск регрессий и повышает поддерживаемость кода.