DIP утверждает, что сущности должны или должны зависеть от абстракций, а не от низкоуровневого модуля. Прочитав эту статью, вы получите реальное представление о том, как реализовать DIP в своих проектах.

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

Это мой последний выпуск примеров SOLID с использованием PHP.
В предыдущих статьях были простые примеры из реальной жизни, иллюстрирующие, как лучшая реализация любого из принципов SOLID в вашем проекте может помочь в разделении.

Ссылки на предыдущие статьи:









Я предположил, что вы, вероятно, закончили статью выше, в которой рассказывается о первых принципах SOLID в объектно-ориентированном дизайне.

Теперь, когда это завершено, давайте посмотрим на DIP на реальном примере и на то, как вы можете написать лучший код, используя любой из принципов SOLID.

Что такое DIP?

DIP — это один из пяти SOLID-принципов объектно-ориентированного проектирования (ООП). Это принцип проектирования, направленный на уменьшение связи между модулями приложения. Короче говоря, этот принцип допускает развязку.

DIP утверждает, что модули высокого уровня не должны зависеть от модулей низкого уровня, но оба должны зависеть от абстракций или интерфейсов.

Как применить DIP в PHP:

Внедрение зависимостей. Вместо того, чтобы создавать объекты непосредственно в классе, вы можете внедрять их как зависимости. Это позволяет легко реализовать зависимости без изменения кода, который их использует.

Используйте инверсию контейнеров управления. Контейнеры инверсии управления (IoC) аналогичны контейнерам внедрения зависимостей, но они также позволяют определять отношения между объектами в вашем приложении. IoC упрощает управление сложными зависимостями.

Существуют и другие способы применения DIP в PHP, но два вышеперечисленных наиболее часто используются фреймворками PHP.

Давайте сократим это и перейдем к практическому примеру реализации DIP.
Мы будем использовать пример, который сначала нарушает DIP, а затем поработаем над лучшей реализацией, которая уважает принцип DIP.

Нарушение DIP:

class DatabaseConnection
{
    public function connect()
    {
        // Code to connect to database
    }
}
class User
{
    private $dbConnection;

    public function __construct()
    {
        $this->dbConnection = new DatabaseConnection();
    }

    public function getUserData()
    {
        // Code to retrieve user data using $this->dbConnection
    }
}

// Usage example
$user = new User();
$userData = $user->getUserData();

В этом примере класс User имеет жестко запрограммированную зависимость от класса DatabaseConnection. Поскольку класс DatabaseConnection является конкретным классом, это означает, что класс User полностью зависит от низкоуровневого модуля.

Это нарушает DIP, поскольку модули высокого уровня не должны зависеть от модулей низкого уровня. Вместо этого оба должны зависеть от абстракций.

Я работал над кодовой базой, которая нарушала DIP в приведенном выше примере, да, код или приложение могут работать хорошо, но основной проблемой является разделение.

Как насчет того, чтобы класс User и класс DatabaseConnection зависели от интерфейса, например, у нас может быть интерфейс, который будет поддерживать различные типы DatabaseConnection, и, минуя databaseConnectionInterface как инъекцию, мы можем сделать так, чтобы наш класс User легко подключался к любой БД подключение без нарушения DIP.

Примеры кодов

interface DatabaseConnectionInterface
{
    public function connect();
}
class MySqlConnection implements DatabaseConnectionInterface
{
    public function connect()
    {
        // Code to connect to MySQL database
    }
}
class MariaDBConnection implements DatabaseConnectionInterface
{
    public function connect()
    {
        // Code to connect to mariaDb database
    }
}
class User
{
    private $dbConnection;

    public function __construct(DatabaseConnectionInterface $dbConnection)
    {
        $this->dbConnection = $dbConnection;
    }

    public function getUserData()
    {
        // Code to retrieve user data using $this->dbConnection
    }
}

// Usage example
$mysqlConnection = new MySqlConnection();
$user = new User($mysqlConnection);
$userData = $user->getUserData();

$mariaDbConnection = new MariaDBConnection();
$user = new User($mariaDbConnection);
$userData = $user->getUserData();

В этом примере мы определяем интерфейс DatabaseConnectionInterface, который указывает метод connect(), который должен быть реализован любым классом, который хочет действовать как соединение с базой данных.

Затем мы определяем два конкретных класса, реализующих этот интерфейс, MySqlConnection и MariaDBConnection, которые подключаются к базам данных MySQL и MariaDB соответственно. Мы также определяем класс User, который принимает объект DatabaseConnectionInterface в качестве параметра конструктора.

Этот класс использует метод connect() объекта DatabaseConnectionInterface для получения пользовательских данных.

Используя интерфейс и внедрение зависимостей, класс User не зависит от конкретной реализации подключения к базе данных.

Вместо этого он зависит от абстракции (DatabaseConnectionInterface), которая может быть реализована любым конкретным классом, реализующим интерфейс. Это делает класс User более гибким и простым в тестировании и обслуживании.

Заключение

На этом принципы SOLID с реальными примерами в PHP заканчиваются, и я надеюсь, что мои примеры и небольшие усилия, направленные на то, чтобы помочь вам понять реализацию SOLID в PHP, были вам полезны.

Надеюсь, вы смогли найти мои статьи о SOLID полезными, поскольку, как люди, мы не безошибочны в этом, если вы считаете, что что-то должно быть добавлено или удалено, пожалуйста, поделитесь своими мыслями в качестве ответа.

Удачной реализации чистого кода !!