SRP — Một class, một trách nhiệm
Nội dung bài · 5 mục
- 1.Khái niệm
- 2.Ví dụ
- 3.Thử ngay
- 4.Lỗi hay gặp
- 5.Tóm tắt
Class OrderService vừa tính tiền, vừa lưu file, vừa gửi email, nên đổi
thuế, đổi nơi lưu hay đổi mẫu email đều phải sửa nó. Sửa chỗ này dễ làm hỏng
chỗ kia. SRP là nguyên tắc đầu tiên của SOLID, giúp tránh đúng chuyện này.
Khái niệm
🎯 SRP (Single Responsibility Principle): mỗi class chỉ nên có một lý do để thay đổi.
"Một lý do để thay đổi" thường ứng với một nhóm người yêu cầu sửa: kế toán lo cách tính tiền, bộ phận vận hành lo nơi lưu dữ liệu, marketing lo nội dung email.
Ví dụ
// Main.java
void main() {
var calculator = new OrderCalculator();
var notifier = new OrderNotifier();
long total = calculator.total(200000);
notifier.send("an@shop.vn", total);
}
// OrderCalculator.java
class OrderCalculator {
public long total(long subtotal) {
return subtotal + subtotal * 10 / 100;
}
}
// OrderNotifier.java
class OrderNotifier {
public void send(String email, long total) {
System.out.println(
"Gửi " + email + ": " + total + "đ");
}
}OrderCalculatorchỉ tính tiền. Đổi thuế thì chỉ sửa class này.OrderNotifierchỉ gửi thông báo. Đổi nội dung thông báo thì chỉ sửa class này.- Mỗi class nhỏ, đọc nhanh, và sửa một class không đụng tới class kia.
Thử ngay
Chạy ví dụ trên bằng java Main.java. Sau đó đổi thuế từ 10% sang 8% trong
OrderCalculator và chạy lại.
Đoán trước khi chạy: lần chạy đầu và lần chạy sau khi đổi thuế in ra số tiền bao nhiêu?
Xem kết quả
Gửi an@shop.vn: 220000đ
Gửi an@shop.vn: 216000đDòng đầu là lần chạy với 10%, dòng sau là lần chạy với 8%. Việc đổi thuế chỉ
chạm vào OrderCalculator, còn OrderNotifier giữ nguyên.
Lỗi hay gặp
Một class ôm mọi việc. Ba lý do để sửa nằm chung một chỗ.
// SAI — tính tiền, lưu file, gửi email chung một class
// OrderService.java
class OrderService {
public long total(long subtotal) {
return subtotal + subtotal * 10 / 100;
}
public void saveToFile(long total) {
System.out.println("Lưu file: " + total);
}
public void sendEmail(String email) {
System.out.println("Gửi " + email);
}
}// ĐÚNG — mỗi class một lý do để thay đổi
// OrderCalculator.java
class OrderCalculator {
public long total(long subtotal) {
return subtotal + subtotal * 10 / 100;
}
}
// OrderFileStore.java
class OrderFileStore {
public void save(long total) {
System.out.println("Lưu file: " + total);
}
}
// OrderNotifier.java
class OrderNotifier {
public void send(String email) {
System.out.println("Gửi " + email);
}
}Tóm tắt
- SRP: mỗi class chỉ có một lý do để thay đổi.
- Lý do thay đổi thường ứng với một nhóm người hay một phần nghiệp vụ.
- Class làm nhiều việc thì sửa một việc dễ làm hỏng việc khác.
- Chia theo lý do thay đổi, đừng chia vụn cho có.
Tự kiểm tra
0/3 câuClass Invoice có các method: calculate(), printPdf(), saveToDatabase(). Class này có mấy lý do để thay đổi?
Cách tách nào hợp lý nhất cho class Invoice ở câu trên?
Câu nào mô tả đúng SRP?