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
Personvà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
Personchịu trách nhiệm quản lý thông tin của đối tượng. - Lớp
PersonDBchị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.

Các kiểu dữ liệu trong C ( int - float - double - char ...)
Thuật toán tìm ước chung lớn nhất trong C/C++
Cấu trúc lệnh switch case trong C++ (có bài tập thực hành)
ComboBox - ListBox trong lập trình C# winforms
Random trong Python: Tạo số random ngẫu nhiên
Lệnh cin và cout trong C++
Cách khai báo biến trong PHP, các loại biến thường gặp
Download và cài đặt Vertrigo Server
Thẻ li trong HTML
Thẻ article trong HTML5
Cấu trúc HTML5: Cách tạo template HTML5 đầu tiên
Cách dùng thẻ img trong HTML và các thuộc tính của img
Thẻ a trong HTML và các thuộc tính của thẻ a thường dùng