SOLID — это акроним, представляющий пять основных принципов объектно-ориентированного программирования и проектирования. Эти принципы помогают создавать более гибкие, понятные и поддерживаемые системы.
1. Single Responsibility Principle (Принцип единственной ответственности)
Класс должен иметь только одну причину для изменения, то есть он должен выполнять только одну задачу.
class User {
private $name;
private $email;
public function __construct($name, $email) {
$this->name = $name;
$this->email = $email;
}
public function getName() {
return $this->name;
}
public function getEmail() {
return $this->email;
}
}
class UserRepository {
public function save(User $user) {
// Логика сохранения пользователя в базу данных
}
}
2. Open/Closed Principle (Принцип открытости/закрытости)
Классы должны быть открыты для расширения, но закрыты для модификации.
abstract class Shape {
abstract public function area();
}
class Rectangle extends Shape {
private $width;
private $height;
public function __construct($width, $height) {
$this->width = $width;
$this->height = $height;
}
public function area() {
return $this->width * $this->height;
}
}
class Circle extends Shape {
private $radius;
public function __construct($radius) {
$this->radius = $radius;
}
public function area() {
return pi() * $this->radius * $this->radius;
}
}
class AreaCalculator {
public function calculateArea(Shape $shape) {
return $shape->area();
}
}
3. Liskov Substitution Principle (Принцип подстановки Барбары Лисков)
Объекты в программе должны быть заменяемы экземплярами их подтипов без изменения правильности выполнения программы.
class Bird {
public function fly() {
// Логика полета
}
}
class Sparrow extends Bird {
public function fly() {
// Логика полета воробья
}
}
class Ostrich extends Bird {
public function fly() {
throw new Exception("Ostriches can't fly");
}
}
// Пример использования
function makeBirdFly(Bird $bird) {
$bird->fly();
}
$sparrow = new Sparrow();
$ostrich = new Ostrich();
makeBirdFly($sparrow); // Работает нормально
makeBirdFly($ostrich); // Выбросит исключение, что нарушает LSP
4. Interface Segregation Principle (Принцип разделения интерфейса)
Клиенты не должны зависеть от интерфейсов, которые они не используют. Это означает, что интерфейсы должны быть специфическими, а не общими.
interface Workable {
public function work();
}
interface Eatable {
public function eat();
}
class Human implements Workable, Eatable {
public function work() {
// Логика работы
}
public function eat() {
// Логика еды
}
}
class Robot implements Workable {
public function work() {
// Логика работы
}
}
5. Dependency Inversion Principle (DIP) — Принцип инверсии зависимостей
Зависимости должны быть направлены на абстракции, а не на конкретные реализации. Это означает, что высокоуровневые модули не должны зависеть от низкоуровневых модулей; и те, и другие должны зависеть от абстракций.
interface DatabaseInterface {
public function connect();
}
class MySQLDatabase implements DatabaseInterface {
public function connect() {
// Код для соединения с MySQL
}
}
class UserRepository {
private $database;
public function __construct(DatabaseInterface $database) {
$this->database = $database;
}
public function save() {
$this->database->connect();
// Логика сохранения пользователя
}
}
// Использование
$database = new MySQLDatabase();
$userRepository = new UserRepository($database);
$userRepository->save();