Классы должны быть открыты для расширения, но закрыты для изменения. Другими словами классы нужно проектировать так чтобы для изменения поведения класса нам не пришлось менять его код.
Например у нас есть класс Product, который логирует ошибки в текстовый файл. Нужно изменить этот класс таким образом, чтобы он логировалл данные в БД, а остальные классы продолжали логировать данные в файл
Было:
class productClass{
protected $logger;
public function __construct(Logger $logger) {
$this->logger = $logger;
}
public function setPrice($price) {
try {
// save price in db
} catch (DbException $e) {
$this->logger->log($e->getMessage());
}
}
}
class Logger {
private function saveToFile($message) {
//...
}
public function log($message) {
//...
$this->saveToFile($message);
}
}
$logger = new Logger();
$product = new Product($logger);
$product->setPrice(10);
Стало:
interface ILogger {
public function log();
}
class FileLogger implements ILogger {
private function saveToFile($message) {
//...
}
public function log($message) {
//...
$this->saveToFile($message);
}
}
class DBLogger implements ILogger {
private function saveToDB($message) {
//...
}
public function log($message) {
//...
$this->saveToDB($message);
}
}
class productClass{
protected $logger;
public function __construct(ILogger $logger) {
$this->logger = $logger;
}
public function setPrice($price) {
try {
// save price in db
} catch (DbException $e) {
$this->logger->log($e->getMessage());
}
}
}
$logger = new DBLogger();
$product = new Product($logger);
$product->setPrice(10);