Ответ
Принцип открытости/закрытости (OCP) — второй принцип SOLID. Он гласит: «Программные сущности (классы, модули, функции) должны быть открыты для расширения, но закрыты для модификации».
- «Закрыты для модификации»: Исходный код стабильной, протестированной сущности не должен изменяться для добавления новой функциональности.
- «Открыты для расширения»: Поведение сущности можно расширить, создавая новые классы, реализующие её интерфейс (абстракцию).
Проблема (нарушение OCP):
class Logger {
func log(message: String, to type: String) {
if type == "console" {
print(message)
} else if type == "file" {
// Запись в файл
}
// Добавление нового типа лога (например, "network") требует изменения этого метода!
}
}
Решение (соблюдение OCP через абстракцию):
// Абстракция, закрытая для модификации
protocol LogDestination {
func write(_ message: String)
}
// Расширения, открытые для добавления
class ConsoleDestination: LogDestination {
func write(_ message: String) { print(message) }
}
class FileDestination: LogDestination {
func write(_ message: String) { /* Запись в файл */ }
}
class NetworkDestination: LogDestination {
func write(_ message: String) { /* Отправка по сети */ }
}
// Класс Logger теперь стабилен
class Logger {
private let destination: LogDestination
init(destination: LogDestination) {
self.destination = destination
}
func log(message: String) {
destination.write(message)
}
}
// Использование
let logger = Logger(destination: NetworkDestination())
logger.log("Test message")
Выгода: Чтобы добавить новый способ логирования, мы создаем новый класс, реализующий LogDestination, не трогая существующий код Logger, ConsoleDestination или FileDestination. Это снижает риск появления новых ошибок в уже работающем коде.