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

  1. 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.
  2. Dễ mở rộng: Thay đổi implementation (DB, logger, payment gateway) mà không cần sửa code logic chính.
  3. Dễ test: Có thể inject MockDatabase để test mà không cần DB thật.
  4. 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.
  5. 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

  1. 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.
  2. 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.
  3. 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.
  4. 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 độ.
Pages: 1 2 3 4 5 6