SOLID (Phần 1): Giới thiệu về SOLID và Nguyên tắc Trách nhiệm Đơn lẻ (Single Responsibility Principle - SRP)

SOLID (Phần 1): Giới thiệu về SOLID và Nguyên tắc Trách nhiệm Đơn lẻ (Single Responsibility Principle - SRP)

Xem nhanh

SOLID là một tập hợp các nguyên tắc thiết kế phần mềm nhằm mục đích làm cho phần mềm dễ hiểu, linh hoạt, và dễ bảo trì hơn. Đây là những nguyên tắc định hướng cho việc viết mã mà bạn có thể dễ dàng thay đổi mà không ảnh hưởng tiêu cực tới các phần khác của hệ thống. Các nguyên tắc SOLID bao gồm:

  • S - Single Responsibility Principle (Nguyên tắc trách nhiệm đơn lẻ):

    • Mỗi lớp chỉ nên có một lý do duy nhất để thay đổi, nghĩa là nó chỉ nên có một trách nhiệm.
    • Nguyên tắc này giúp giảm thiểu sự phức tạp của một lớp và làm cho mã dễ hiểu hơn và dễ bảo trì hơn.
  • O - Open/Closed Principle (Nguyên tắc mở/đóng):

    • Các thực thể phần mềm (lớp, module, hàm,...) nên được mở để mở rộng nhưng đóng để sửa đổi.
    • Điều này có nghĩa là bạn có thể mở rộng chức năng của lớp mà không cần thay đổi mã nguồn gốc.
  • L - Liskov Substitution Principle (Nguyên tắc thay thế Liskov):

    • Các đối tượng của một chương trình nên có thể được thay thế bằng các thể hiện của các lớp con của chúng mà không làm thay đổi các tính chất đúng đắn của chương trình.
    • Điều này đảm bảo rằng một lớp con có thể thay thế lớp cha mà không làm ảnh hưởng đến tính đúng đắn của ứng dụng.
  • I - Interface Segregation Principle (Nguyên tắc phân chia giao diện):

    • Nhiều giao diện phụ đặc biệt tốt hơn một giao diện tổng thể.
    • Khách hàng không nên bị ép buộc phải dựa vào những giao diện mà họ không sử dụng. Đây là về việc tạo ra các giao diện đơn giản, tập trung vào nhu cầu cụ thể.
  • D - Dependency Inversion Principle (Nguyên tắc đảo ngược sự phụ thuộc):

    • Các module cấp cao không nên phụ thuộc vào các module cấp thấp. Cả hai nên phụ thuộc vào các abstraction.
    • Abstraction không nên phụ thuộc vào chi tiết. Chi tiết nên phụ thuộc vào abstraction.
    • Áp dụng các nguyên tắc SOLID giúp cải thiện cấu trúc mã, làm cho nó dễ dàng quản lý và mở rộng, đồng thời giảm thiểu lỗi phát sinh khi sửa đổi phần mềm trong tương lai.

Nguyên tắc Trách nhiệm Đơn lẻ (Single Responsibility Principle - SRP)

  • Nguyên tắc Trách nhiệm Đơn lẻ (Single Responsibility Principle - SRP) trong lập trình là một trong năm nguyên tắc của SOLID nhằm giúp thiết kế phần mềm trở nên dễ hiểu hơn, dễ bảo trì và linh hoạt. Nguyên tắc này được phát biểu đơn giản như sau:
  • Mỗi lớp chỉ nên có một lý do duy nhất để thay đổi.
  • Cụ thể hơn, điều này có nghĩa là một lớp chỉ nên có một trách nhiệm hay chức năng duy nhất. Khi một lớp chỉ đảm nhận một nhiệm vụ, thì các thay đổi hoặc yêu cầu mới liên quan đến chức năng đó sẽ chỉ tác động lên duy nhất lớp đó, và sẽ không ảnh hưởng tới các phần khác của hệ thống.

Tại sao SRP quan trọng?

  1. Dễ Bảo Trì: Khi một lớp chỉ chịu trách nhiệm về một nhiệm vụ, nó ít có khả năng bị ảnh hưởng khi các phần khác của hệ thống thay đổi. Điều này làm cho mã dễ đọc và dễ bảo trì.
  2. Tái Sử Dụng: Lớp có trách nhiệm đơn lẻ thường độc lập, cho phép tái sử dụng trong các dự án khác mà không cần tái cấu trúc lại.
  3. Phát Hiện Lỗi: Khi mã bị lỗi, có thể dễ dàng xác định và sửa lỗi hơn vì bạn biết chính xác lớp nào đang xử lý phần bị ảnh hưởng.
  4. Quản Lý Dễ Dàng: Dễ dàng quản lý phức tạp, minh bạch hơn giúp lập trình viên khác hiểu mã nguồn mà không cần nhiều nỗ lực.

Dưới đây là một ví dụ minh họa nguyên tắc Single Responsibility Principle (SRP) được thực hiện bằng PHP:

Ví dụ không tuân theo SRP, Trước tiên, hãy xem một lớp Employee không tuân theo SRP:

Copy
<?php

class Employee {
    private $id;
    private $name;
    private $salary;

    public function __construct($id, $name, $salary) {
        $this->id = $id;
        $this->name = $name;
        $this->salary = $salary;
    }

    // Trách nhiệm tính thuế
    public function calculateTax() {
        return $this->salary * 0.25;
    }

    // Trách nhiệm lưu trữ thông tin nhân viên trong cơ sở dữ liệu
    public function saveToDatabase() {
        // Giả sử kết nối và lưu dữ liệu vào cơ sở dữ liệu
        echo "Saving $this->name to the database.";
    }
}

?>
  • Vấn đề: Lớp Employee ở trên có ba trách nhiệm: quản lý thông tin nhân viên, tính toán thuế, và lưu trữ dữ liệu. Đây là một sự vi phạm của SRP.
  • Ví dụ tuân theo SRP. Dưới đây là cách tách các trách nhiệm ra thành các lớp riêng lẻ:
Copy
<?php

class Employee {
    private $id;
    private $name;
    private $salary;

    public function __construct($id, $name, $salary) {
        $this->id = $id;
        $this->name = $name;
        $this->salary = $salary;
    }

    public function getId() {
        return $this->id;
    }

    public function getName() {
        return $this->name;
    }

    public function getSalary() {
        return $this->salary;
    }
}

class SalaryCalculator {
    public function calculateTax(Employee $employee) {
        return $employee->getSalary() * 0.25;
    }
}

class EmployeeRepository {
    public function save(Employee $employee) {
        // Giả sử kết nối và lưu dữ liệu vào cơ sở dữ liệu
        echo "Saving " . $employee->getName() . " to the database.";
    }
}

// Ví dụ sử dụng
$employee = new Employee("1", "John Doe", 5000);
$calculator = new SalaryCalculator();
$tax = $calculator->calculateTax($employee);

$repository = new EmployeeRepository();
$repository->save($employee);

echo "Tax for " . $employee->getName() . " is " . $tax;

?>

Lợi ích

  1. Tách biệt trách nhiệm: Employee chỉ quản lý dữ liệu, SalaryCalculator tính thuế, và EmployeeRepository lo việc lưu trữ.
  2. Dễ bảo trì: Nếu có bất kỳ thay đổi nào trong logic tính thuế hoặc phương thức lưu trữ, bạn chỉ cần thay đổi trong các lớp liên quan mà không ảnh hưởng đến hệ thống còn lại.
  3. Tái sử dụng: Các lớp hiện tại có thể được sử dụng trong các phần khác của ứng dụng một cách độc lập.
  4. Bằng cách áp dụng SRP, bạn tạo ra một cấu trúc mã rõ ràng và dễ quản lý, giúp cải thiện chất lượng và khả năng mở rộng của phần mềm.

Các bài viết cùng chủ đề