Nguyên tắc Single Responsibility (SRP) trong Design Pattern là một trong năm nguyên tắc cơ bản của SOLID. Nguyên tắc này phát biểu rằng một lớp chỉ nên có duy nhất một lý do để thay đổi, nghĩa là nó chỉ nên chịu trách nhiệm cho một nhiệm vụ, hành động, hoặc phần việc nhất định.
Giải thích chi tiết
Nguyên tắc này tập trung vào việc phân chia trách nhiệm một cách rõ ràng và cụ thể. Mỗi lớp trong hệ thống chỉ nên đảm nhiệm một phần công việc cụ thể, và nó không nên bị tác động bởi sự thay đổi của các phần việc khác. Điều này giúp giảm độ phức tạp của hệ thống, dễ bảo trì, và dễ mở rộng hơn.
Nếu một lớp đảm nhận quá nhiều nhiệm vụ, có nhiều trách nhiệm khác nhau, thì khi có một thay đổi xảy ra ở một nhiệm vụ nào đó, nó có thể làm ảnh hưởng đến các nhiệm vụ khác, gây ra sự phụ thuộc lẫn nhau và dẫn đến lỗi không mong muốn.
Ví dụ
Giả sử chúng ta có một lớp Employee chịu trách nhiệm về cả việc tính lương và việc lưu trữ thông tin nhân viên trong cơ sở dữ liệu:
public class Employee {
private String name;
private int salary;
public Employee(String name, int salary) {
this.name = name;
this.salary = salary;
}
public int calculateSalary() {
// Tính lương
return salary;
}
public void saveToDatabase() {
// Lưu thông tin nhân viên vào cơ sở dữ liệu
}
}
Trong ví dụ trên, lớp Employee có hai trách nhiệm:
- Tính lương của nhân viên.
- Lưu trữ thông tin nhân viên vào cơ sở dữ liệu.
Nếu hệ thống thay đổi cách tính lương hoặc thay đổi cách lưu trữ dữ liệu, cả hai trách nhiệm này sẽ phải thay đổi cùng nhau, làm tăng độ phức tạp và khả năng xảy ra lỗi.
Áp dụng nguyên tắc Single Responsibility
Để áp dụng nguyên tắc SRP, chúng ta cần tách hai trách nhiệm này ra thành các lớp khác nhau:
public class Employee {
private String name;
private int salary;
public Employee(String name, int salary) {
this.name = name;
this.salary = salary;
}
public int getSalary() {
return salary;
}
}
public class SalaryCalculator {
public int calculateSalary(Employee employee) {
// Tính lương
return employee.getSalary();
}
}
public class EmployeeRepository {
public void saveToDatabase(Employee employee) {
// Lưu thông tin nhân viên vào cơ sở dữ liệu
}
}
Bằng cách tách các trách nhiệm, chúng ta tạo ra ba lớp khác nhau, mỗi lớp đảm nhiệm một phần việc cụ thể:
- Employee: Chỉ giữ thông tin của nhân viên.
- SalaryCalculator: Tính lương cho nhân viên.
- EmployeeRepository: Lưu trữ thông tin nhân viên vào cơ sở dữ liệu.
Lợi ích của nguyên tắc Single Responsibility
- Dễ bảo trì: Khi một lớp chỉ có một trách nhiệm duy nhất, thay đổi trong hệ thống sẽ dễ dàng hơn vì chỉ cần điều chỉnh một phần mã mà không làm ảnh hưởng đến các phần khác.
- Tăng tính tái sử dụng: Các lớp được tách ra với các nhiệm vụ riêng biệt sẽ có tính tái sử dụng cao hơn trong các ngữ cảnh khác nhau.
- Giảm độ phức tạp: Việc chia nhỏ trách nhiệm giúp mã nguồn dễ hiểu hơn và dễ kiểm tra hơn.
Kết luận
Nguyên tắc Single Responsibility là một nguyên tắc quan trọng giúp đảm bảo rằng mỗi lớp trong hệ thống chỉ có một trách nhiệm duy nhất, giúp hệ thống dễ bảo trì, mở rộng, và tránh các lỗi không cần thiết. Điều này cũng giúp mã nguồn trở nên rõ ràng và dễ hiểu hơn, góp phần vào việc phát triển phần mềm hiệu quả.