Open/closed principle, OCP - Принцип открытости | закрытости.

Классы должны быть открыты для расширения, но закрыты для изменения. Другими словами классы нужно проектировать так чтобы для изменения поведения класса нам не пришлось менять его код.

Например у нас есть класс 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);