Tell about the letter D in SOLID and its connection to interfaces.
sobes.tech AI
Answer from AI
D in SOLID stands for the Dependency Inversion Principle (DIP).
The principle states:
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
- Abstractions should not depend on details. Details should depend on abstractions.
The essence of DIP is that high-level policies should not depend on low-level implementations directly. Instead, both should depend on abstractions (interfaces or abstract classes).
Relation to interfaces:
Interfaces act as these abstractions. They define a contract that a specific implementation must fulfill.
Example without DIP:
<?php
class MySqlConnection {
public function connect() {
// MySQL connection details
}
}
class UserRepository {
private $dbConnection;
public function __construct() {
$this->dbConnection = new MySqlConnection(); // Dependency on a specific implementation
}
public function getUserById($id) {
$this->dbConnection->connect();
// Logic to get user
}
}
In this example, UserRepository (a high-level module representing business logic) directly depends on MySqlConnection (a low-level module representing implementation details). If you need to switch to PostgreSQL, you would have to change UserRepository.
Example with DIP and using an interface:
<?php
interface DbConnectionInterface { // Abstraction
public function connect();
}
class MySqlConnection implements DbConnectionInterface { // Implementation detail depending on abstraction
public function connect() {
// MySQL connection details
}
}
class PgSqlConnection implements DbConnectionInterface { // Another implementation depending on abstraction
public function connect() {
// PostgreSQL connection details
}
}
class UserRepository { // High-level module depending on abstraction
private $dbConnection;
public function __construct(DbConnectionInterface $dbConnection) { // Dependency on abstraction
$this->dbConnection = $dbConnection;
}
public function getUserById($id) {
$this->dbConnection->connect();
// Logic to get user
}
}
// Usage
$mysqlConn = new MySqlConnection();
$userRepoMysql = new UserRepository($mysqlConn);
$pgsqlConn = new PgSqlConnection();
$userRepoPgsql = new UserRepository($pgsqlConn);
In this improved example, UserRepository depends on the DbConnectionInterface interface, not on a specific implementation. This makes it easy to change the database type by passing different implementations of this interface to the constructor of UserRepository.
Thus, interfaces play a key role in implementing DIP by providing abstractions that allow high-level modules to remain independent of low-level implementation details. This increases flexibility, testability, and maintainability of the code.