Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.
Single Responsibility Principle trong Python
Trong bài viết này, bạn sẽ được tìm hiểu về nguyên tắc trách nhiệm đơn lẻ (Single Responsibility Principle - SRP), một trong những nguyên tắc cơ bản của thiết kế phần mềm theo chuẩn SOLID. Nguyên tắc này giúp đảm bảo rằng mỗi lớp, phương thức, hoặc hàm chỉ có một nhiệm vụ duy nhất, từ đó cải thiện tính dễ bảo trì, mở rộng và kiểm thử của mã nguồn. Mình sẽ cùng tìm hiểu cách áp dụng SRP trong Python qua các ví dụ cụ thể và rõ ràng.
SOLID là gì?
SOLID là tập hợp năm nguyên tắc thiết kế phần mềm được biên soạn bởi "Uncle Bob":
- S – Single Responsibility Principle (Nguyên tắc Trách nhiệm Đơn lẻ)
- O – Open-Closed Principle (Nguyên tắc Mở-Đóng)
- L – Liskov Substitution Principle (Nguyên tắc Thay thế Liskov)
- I – Interface Segregation Principle (Nguyên tắc Phân tách Interface)
- D – Dependency Inversion Principle (Nguyên tắc Đảo ngược Phụ thuộc)
Nguyên tắc trách nhiệm đơn lẻ là nguyên tắc đầu tiên trong bộ nguyên tắc SOLID.
Giới thiệu về nguyên tắc trách nhiệm đơn lẻ trong Python
Nguyên tắc trách nhiệm đơn lẻ (SRP) quy định rằng mỗi lớp, phương thức, hoặc hàm chỉ nên đảm nhiệm một chức năng duy nhất hoặc có một lý do để thay đổi.
Bài viết này được đăng tại [free tuts .net]
Mục tiêu của nguyên tắc trách nhiệm đơn lẻ là:
- Tạo ra các lớp, phương thức, và hàm có tính liên kết cao và bền vững.
- Thúc đẩy việc xây dựng các lớp có tính hợp thành (composition).
- Tránh sự trùng lặp mã nguồn.
Hãy xem ví dụ sau về lớp Person
:
class Person: def __init__(self, name): self.name = name def __repr__(self): return f'Person(name={self.name})' @classmethod def save(cls, person): print(f'Save the {person} to the database') if __name__ == '__main__': p = Person('John Doe') Person.save(p)
Trong ví dụ này, lớp Person
có hai nhiệm vụ:
- Quản lý thông tin của đối tượng
Person
. - Lưu đối tượng
Person
vào cơ sở dữ liệu.
Nếu sau này bạn muốn lưu đối tượng Person
vào một nơi lưu trữ khác như file, bạn sẽ phải thay đổi phương thức save()
, điều này dẫn đến thay đổi toàn bộ lớp Person
.
Tách biệt trách nhiệm theo nguyên tắc SRP trong Python
Để lớp Person
tuân theo nguyên tắc trách nhiệm đơn lẻ, ta cần tách nhiệm vụ lưu trữ đối tượng thành một lớp khác. Ví dụ:
class Person: def __init__(self, name): self.name = name def __repr__(self): return f'Person(name={self.name})' class PersonDB: def save(self, person): print(f'Save the {person} to the database') if __name__ == '__main__': p = Person('John Doe') db = PersonDB() db.save(p)
Ở thiết kế này, chúng ta tách lớp Person
thành hai lớp:
- Lớp
Person
chịu trách nhiệm quản lý thông tin của đối tượng. - Lớp
PersonDB
chịu trách nhiệm lưu trữ đối tượng vào cơ sở dữ liệu.
Nếu bạn muốn lưu đối tượng Person
vào một nơi lưu trữ khác, bạn chỉ cần định nghĩa một lớp khác mà không phải thay đổi lớp Person
.
Sử dụng Facade Pattern để tiện lợi hơn trong Python
Thiết kế trên có một vấn đề là bạn phải làm việc với hai lớp: Person
và PersonDB
. Để tiện lợi hơn, bạn có thể áp dụng Facade Pattern (Mẫu mặt tiền) để lớp Person
làm giao diện cho lớp PersonDB
:
class PersonDB: def save(self, person): print(f'Save the {person} to the database') class Person: def __init__(self, name): self.name = name self.db = PersonDB() def __repr__(self): return f'Person(name={self.name})' def save(self): self.db.save(person=self) if __name__ == '__main__': p = Person('John Doe') p.save()
Kết bài
Việc áp dụng nguyên tắc trách nhiệm đơn lẻ giúp bạn xây dựng mã nguồn có tính tổ chức cao, dễ bảo trì và mở rộng. Khi mỗi lớp, phương thức hoặc hàm chỉ thực hiện một nhiệm vụ duy nhất, bạn có thể giảm thiểu sự phụ thuộc, tránh được những thay đổi không mong muốn và dễ dàng phát hiện cũng như sửa lỗi. Đó là lý do vì sao SRP là một trong những nguyên tắc quan trọng của thiết kế phần mềm, giúp tạo ra những hệ thống linh hoạt và bền vững.