Nguyên tắc SOLID

Nguyên tắc SOLID là một tập hợp các nguyên tắc thiết kế phần mềm được đưa ra để giúp tạo ra mã nguồn linh hoạt, dễ bảo trì và mở rộng. SOLID là một từ viết tắt của các nguyên tắc sau:

Nguyên tắc SOLID
  1. Nguyên tắc đơn trách nhiệm (Single Responsibility Principle - SRP):

    • Một lớp nên chỉ có một lý do để thay đổi.
    • Một lớp nên chỉ đảm nhiệm một trách nhiệm duy nhất.
  2. Nguyên tắc đóng mở (Open/Closed Principle - OCP):

    • Phần mềm nên được thiết kế sao cho có thể mở rộng, nhưng không cần phải sửa đổi mã nguồn hiện tại.
    • Mở rộng phải được thực hiện thông qua việc thêm mới, không phải sửa đổi.
  3. Nguyên tắc thay thế Liskov (Liskov Substitution Principle - LSP):

    • Các đối tượng của một lớp con nên có thể thay thế các đối tượng của lớp cha mà không làm thay đổi tính đúng đắn của chương trình.
  4. Nguyên tắc giao diện đồng nhất (Interface Segregation Principle - ISP):

    • Khách hàng không nên bị buộc phải phụ thuộc vào các giao diện mà chúng không sử dụng.
    • Một lớp không nên phải triển khai các phương thức mà nó không sử dụng.
  5. Nguyên tắc phụ thuộc đảo ngược (Dependency Inversion Principle - DIP):

    • Các module cấp cao không nên phụ thuộc vào các module cấp thấp, mà cả hai nên phụ thuộc vào các abstraction.
    • Interface (giao diện) làm cầu nối giữa các module.

Dưới đây là một số ví dụ cụ thể để minh họa các nguyên tắc SOLID:

  1. Nguyên tắc Đơn Trách Nhiệm (SRP):

    • Không tốt: Một lớp Quản lý Người dùng (UserManager) thực hiện cả việc xử lý đăng nhập và gửi email thông báo.
    • Tốt hơn: Tạo một lớp Đăng nhập (LoginService) và một lớp Gửi Email (EmailSender), mỗi lớp có một trách nhiệm cụ thể.
  2. Nguyên tắc Đóng Mở (OCP):

    • Không tốt: Một lớp Xử lý Đơn đặt hàng (OrderProcessor) có một phương thức lớn để xử lý mọi loại đơn đặt hàng.
    • Tốt hơn: Sử dụng mô hình Strategy để có thể mở rộng bằng cách thêm mới các chiến lược xử lý đơn đặt hàng mà không cần sửa đổi lớp OrderProcessor.
  3. Nguyên tắc Thay Thế Liskov (LSP):

    • Không tốt: Một lớp Chim (Bird) có phương thức fly(). Tạo một lớp Chim Đi (WalkingBird) thừa kế từ Bird nhưng không triển khai phương thức fly().
    • Tốt hơn: Đảm bảo rằng tất cả các lớp con có thể thay thế cho lớp cha mà không làm thay đổi tính đúng đắn của chương trình.
  4. Nguyên tắc Giao Diện Đồng Nhất (ISP):

    • Không tốt: Một giao diện Quản lý (ManagerInterface) có nhiều phương thức, trong đó một số phương thức không được sử dụng bởi một số lớp.
    • Tốt hơn: Tách thành nhiều giao diện nhỏ hơn, mỗi giao diện đảm bảo rằng chỉ một lớp sử dụng phương thức cụ thể.
  5. Nguyên tắc Phụ Thuộc Đảo Ngược (DIP):

    • Không tốt: Một lớp Service cao cấp phụ thuộc trực tiếp vào một lớp Repository cụ thể.
    • Tốt hơn: Sử dụng Dependency Injection hoặc Inversion of Control để làm cho các lớp cao cấp phụ thuộc vào abstraction (interface) thay vì các lớp cụ thể.

Bằng cách áp dụng những nguyên tắc này, bạn có thể tạo ra mã nguồn linh hoạt, dễ bảo trì, và dễ mở rộng, giảm thiểu sự phụ thuộc giữa các thành phần trong hệ thống.