SOLID là một tập hợp của năm nguyên tắc lập trình quan trọng, được Robert C. Martin, còn được biết đến với tên Uncle Bob, đề xuất. Những nguyên tắc này được thiết kế để giúp ngăn chặn việc phát sinh các vấn đề phổ biến trong lập trình, giúp code dễ bảo dưỡng, mở rộng và tái sử dụng.

Năm nguyên tắc trong SOLID bao gồm:

  • Single Responsibility Principle (SRP)  – Nguyên tắc trách nhiệm đơn lẻ.
  • Open/Closed Principle (OCP) – Nguyên tắc mở/đóng.
  • Liskov Substitution Principle (LSP) – Nguyên tắc thay thế Liskov.
  • Interface Segregation Principle (ISP) – Nguyên tắc phân tách giao diện.
  • Dependency Inversion Principle (DIP) –  Nguyên tắc đảo ngược phụ thuộc.

Single responsibility principle

Mỗi lớp chỉ nên đảm nhận một nhiệm vụ cụ thể. Single responsibility là nguyên tắc đầu tiên, ứng với chữ “S” trong bộ nguyên tắc SOLID, nhấn mạnh rằng mỗi lớp chỉ nên đảm nhận một trách nhiệm duy nhất. Việc gán quá nhiều nhiệm vụ cho một lớp sẽ khiến lớp này trở nên phức tạp, khó hiểu và khó bảo trì. Trong ngành IT, yêu cầu thay đổi và bổ sung chức năng là điều thường xuyên xảy ra nên việc sở hữu code rõ ràng, dễ hiểu là vô cùng quan trọng.

Open/Closed principle

Không sửa đổi lớp có sẵn, thay vào đó hãy mở rộng bằng kế thừa. Open/Closed là nguyên tắc thứ hai trong SOLID, tương ứng với chữ “O” nhấn mạnh rằng khi cần bổ sung chức năng cho chương trình, ta nên tạo lớp mới kế thừa (hoặc sử dụng) lớp cũ thay vì chỉnh sửa trực tiếp lớp hiện tại. Điều này khiến chương trình có nhiều lớp hơn, nhưng bù lại ta không cần kiểm thử lại các lớp cũ mà chỉ tập trung vào các lớp mới.

Liskov substitution principle

Đối tượng (instance) của lớp con có thể thay thế cho đối tượng của lớp cha mà không gây lỗi. Liskov substitution là nguyên tắc thứ 3 trong bộ nguyên tắc SOLID, tương ứng với chữ “L”. Nguyên tắc này quy định rằng các lớp con phải kế thừa và duy trì hành vi cơ bản của lớp cha. Nếu vi phạm nguyên tắc này, chương trình có thể gặp lỗi khi sử dụng các đối tượng của lớp con thay thế cho các đối tượng của lớp cha.

Interface segregation principle

Thay vì sử dụng một giao diện (interface) lớn, hãy tách thành nhiều giao diện nhỏ hơn với các mục đích cụ thể. Interface segregation là nguyên tắc thứ 4 trong bộ nguyên tắc SOLID, tương ứng với chữ “I”. Bạn hãy tưởng tượng đang đối mặt với một interface khổng lồ có khoảng 100 methods. Lúc này, việc implements interface rất khó khăn bởi vì các lớp buộc phải thực thi tất cả các method trong interface. Điều này dẫn đến tình trạng dư thừa khi một lớp không cần sử dụng hết 100 methods đó.

Dependency inversion principle

Các module cấp cao không nên phụ thuộc vào các module cấp thấp. Cả hai nên phụ thuộc vào abstractions (sự trừu tượng).

Có thể hiểu như sau, các thành phần trong một chương trình chỉ nên phụ thuộc vào các khái niệm trừu tượng (abstractions). Các khái niệm trừu tượng này không nên phụ thuộc vào những chi tiết cụ thể mà ngược lại, chính những chi tiết cụ thể nên phụ thuộc vào chúng.

Các khái niệm trừu tượng là những yếu tố ổn định, ít biến đổi, chúng bao gồm những đặc tính chung nhất của các yếu tố cụ thể. Dù các yếu tố cụ thể có thể rất khác nhau nhưng chúng vẫn tuân theo những nguyên tắc chung mà khái niệm trừu tượng đã định nghĩa. Sự phụ thuộc vào khái niệm trừu tượng giúp cho chương trình trở nên linh hoạt và thích ứng tốt hơn với các thay đổi liên tục.

Khi áp dụng SOLID vào viết code, lập trình viên sẽ nhận được nhiều lợi ích như:

  • Giảm thiểu sự phức tạp: SOLID giúp chia nhỏ phần mềm thành các thành phần độc lập, mỗi thành phần đảm nhiệm một chức năng riêng biệt. Nhờ vậy, code trở nên dễ đọc, dễ hiểu và dễ dàng sửa đổi hơn.
  • Dễ dàng bảo trì và mở rộng: Khi cần thay đổi, bạn chỉ cần tác động vào một phần nhỏ thay vì ảnh hưởng đến toàn bộ hệ thống. Nhờ vậy, việc bảo trì và mở rộng phần mềm trở nên đơn giản và hiệu quả hơn, đặc biệt là đối với các dự án lớn.
  • Tăng tính linh hoạt và khả năng tái sử dụng: Các thành phần được thiết kế linh hoạt, có thể dễ dàng áp dụng vào các dự án khác nhau, nhờ đó tiết kiệm thời gian và chi phí cho việc phát triển phần mềm.

Design pattern là gì?

Design pattern là các giải pháp tổng thể đã được tối ưu hóa, được tái sử dụng cho các vấn đề phổ biến trong thiết kế phần mềm mà chúng ta thường gặp phải hàng ngày. Đây là tập các giải pháp đã được suy nghĩ, đã giải quyết trong tình huống cụ thể.

Design pattern có tác dụng gì?

  • Giúp sản phẩm của chúng ta linh hoạt, dễ dàng thay đổi và bảo trì hơn.
  • Có một điều luôn xảy ra trong phát triển phần mềm, đó là sự thay đổi về yêu cầu. Lúc này hệ thống phình to, các tính năng mới được thêm vào trong khi performance cần được tối ưu hơn.
  • Design pattern cung cấp những giải pháp đã được tối ưu hóa, đã được kiểm chứng để giải quyết các vấn đề trong software engineering. Các giải pháp ở dạng tổng quát, giúp tăng tốc độ phát triển phần mềm bằng cách đưa ra các mô hình test, mô hình phát triển đã qua kiểm nghiệm.
  • Những lúc khi bạn gặp bất kỳ khó khăn đối với những vấn đề đã được giải quyết rồi, design patterns là hướng đi giúp bạn giải quyết vấn đề thay vì tự tìm kiếm giải pháp tốn kém thời gian.
  • Giúp cho các lập trình viên có thể hiểu code của người khác một cách nhanh chóng (có thể hiểu là các mối quan hệ giữa các module chẳng hạn). Mọi thành viên trong team có thể dễ dàng trao đổi với nhau để cùng xây dựng dự án mà không tốn nhiều thời gian.

Bài viết khác

Language Switching trong Flutter

        Trong quá trình phát triển ứng dụng di động, khả năng hỗ trợ nhiều ngôn ngữ ngày càng trở nên quan trọng. Một ứng dụng chỉ sử dụng duy nhất một ngôn ngữ có thể gặp khó khăn khi tiếp cận người dùng ở các quốc gia và khu vực khác […]

UTC & Local Time Conversion

Trong thời đại toàn cầu hóa, con người thường xuyên làm việc, học tập và giao tiếp với những người ở các quốc gia khác nhau. Một cuộc họp trực tuyến có thể được tổ chức tại Việt Nam, nhưng người tham gia lại đang ở Hoa Kỳ, Anh, Nhật Bản hoặc Australia. Vì vậy, […]

Logging / Monitoring / CI/CD

1. Logging / Monitoring / CI/CD là gì? Trong quá trình phát triển phần mềm, việc viết code để ứng dụng chạy được chỉ là một phần của công việc. Khi đưa ứng dụng vào sử dụng thực tế, lập trình viên còn phải quan tâm đến nhiều vấn đề khác như ứng dụng có […]

Docker

1. Docker là gì? Docker là một nền tảng được sử dụng để đóng gói, triển khai và chạy ứng dụng trong các môi trường độc lập, được gọi là Container. Docker giúp lập trình viên đưa mã nguồn, thư viện, các gói phụ thuộc và những thành phần cần thiết để chạy ứng dụng […]

Unit Testing và Integration Testing

1. Unit Testing và Integration Testing là gì? Unit Testing và Integration Testing là hai phương pháp kiểm thử phần mềm thường được sử dụng trong quá trình phát triển ứng dụng. Mục đích của hai phương pháp này là kiểm tra xem chương trình có hoạt động đúng theo yêu cầu hay không, đồng […]

Message Broker

1. Message Broker là gì? Message Broker là một thành phần trung gian được sử dụng để tiếp nhận, quản lý và chuyển tiếp thông điệp giữa các ứng dụng hoặc các thành phần trong một hệ thống phần mềm. Công nghệ này thường xuất hiện trong những hệ thống Backend, kiến trúc Microservices và […]

Leave a Reply

Your email address will not be published. Required fields are marked *