SOLID Principal
September 8, 2025
D – Dependency Inversion Principle (Nguyên tắc đảo ngược phụ thuộc)
👉 Code nên phụ thuộc vào abstraction (interface), không phụ thuộc vào implementation (class cụ thể).
- Giúp giảm sự ràng buộc, dễ thay thế và test.
Wrong
class MySQLDatabase {
public function query($sql) {}
}
class UserRepository {
private $db;
public function __construct() {
$this->db = new MySQLDatabase(); // phụ thuộc trực tiếp vào MySQL
}
}
Right
interface Database {
public function query($sql);
}
class MySQLDatabase implements Database {
public function query($sql) {}
}
class UserRepository {
private $db;
public function __construct(Database $db) {
$this->db = $db;
}
}
- UserRepository chỉ biết đến Database, không quan tâm đó là MySQL hay PostgreSQL.
- Thay đổi DB chỉ cần inject implementation khác.
Lợi ích của DIP
- Giảm coupling (kết dính chặt chẽ): Module cấp cao không “khóa chặt” với module cấp thấp.
- Dễ mở rộng: Thay đổi implementation (DB, logger, payment gateway) mà không cần sửa code logic chính.
- Dễ test: Có thể inject MockDatabase để test mà không cần DB thật.
- Tăng tính tái sử dụng: Module cấp cao có thể dùng lại trong nhiều hệ thống khác nhau, chỉ cần thay implementation.
- Kết hợp Dependency Injection container: Cho phép cấu hình hệ thống linh hoạt hơn (Spring, Laravel, NestJS đều tận dụng DIP).
Bất cập / Khó khăn
- Tăng độ phức tạp:
- Với dự án nhỏ, việc tạo interface cho mọi thứ có thể dư thừa và làm code rối rắm.
- Quá nhiều abstraction:
- Nếu lạm dụng, ta sẽ có “rừng interface”, mỗi class đi kèm một interface, gây khó đọc.
- Khó theo dõi luồng thực thi:
- Người mới vào dự án phải dò từ abstraction sang implementation → mất thời gian hiểu code.
- Over-engineering:
- Nếu hệ thống chưa chắc chắn cần thay thế implementation, việc áp dụng DIP ngay từ đầu đôi khi chỉ làm chậm tiến độ.
