SOLID là viết tắt của 5 chữ cái đầu trong 5 nguyên tắc thiết kế hướng đối tượng. Giúp cho lập trình viên viết ra những đoạn code dễ đọc, dễ hiểu, dễ maintain. Nó được đưa ra bơi Robert C Martin và Michael Feathers. 5 nguyên tắc đó bao gồm:
• Single responsibility priciple (SRP)
• Open/Closed principle (OCP)
• Liskov substitution principe (LSP)
• Interface segregation principle (ISP)
• Dependency inversion principle (DIP)
Single responsibility priciple (SRP)
• Hiểu đơn giản thì Single responsibility priciple (SRP) : mỗi thành phần nên chỉ thực thi và
chịu trách nhiệm về đúng 1 phần công việc nào đó.
• Ví dụ trong mô hình MVC : sẽ gồm các thành phần như SERVICE, REPOSITORY ,
CONTROLLERS. Thì mỗi thành phần nên chỉ đẩm nhận 1 nhiệm vụ nhất định như service
thì liên quan đến xử lý dữ liệu, repository thì giúp thao tác với database còn controller thì
giúp xử lý và điều hướng các request từ client lên server, ...
Open/Closed principle (OCP)
• Open for extension closed for modification
• Không được sửa đổi một Class có sẵn, nhưng có thể mở rộng bằng kế thừa.
• Theo nguyên lý này, mỗi khi ta muốn thêm chức năng cho chương trình, chúng ta nên viết
class mới mở rộng class cũ (bằng cách kế thừa hoặc sở hữu class cũ) chứ không nên sửa
đổi class cũ. Việc này dẫn đến tình trạng phát sinh nhiều class, nhưng chúng ta sẽ không
cần phải test lại các class cũ nữa, mà chỉ tập trung vào test các class mới, nơi chứa các
chức năng mới.
• Thông thường việc mở rộng thêm chức năng thì phải viết thêm code, vậy để thiết kế ra một
module có thể dễ dàng mở rộng nhưng lại hạn chế sửa đổi code ta cần làm gì. Cách giải
quyết là tách những phần dễ thay đổi ra khỏi phần khó thay đổi mà vẫn đảm bảo không ảnh
hưởng đến phần còn lại.
Liskov substitution principle
• Các đối tượng (instance) kiểu class con có thể thay thế các đối tượng kiểu class cha mà
không gây ra lỗi.
• Tầm quan trọng của nguyên tắc này sẽ rất rõ ràng nếu bạn thấy được hậu quả khi vi phạm nó. Giả sử chúng ta có một hàm f thuộc class cơ sở B. Giả sử chúng ta có một class D được tạo ra dựa vào B mà khi chúng ta gọi hàm f với object của D theo cái cách làm với B, f hoạt động sai. Khi đó, D sẽ vi phạm LSP. Rõ ràng, D trở nên mỏng manh với sự có mặt của f.
• Tác giả của f sẽ cố gắng bổ sung một vài chi tiết để có thể kiểm tra với D do đó f có thể hoạt động tốt khi gọi nó từ một object của D. Cách làm này sẽ vi phạm OCP bởi f không hoàn toàn đóng với tất các class được sinh ra từ B. Code trở nên có mùi và nó rõ ràng là kết quả của một lập trình viên thiếu kinh nghiệm (hoặc, tồi tệ hơn, một lập trình viên vội vàng) cố gắng giải quyết mâu thuẫn với LSP.
Interface segregation principle
• Thay vì dùng 1 interface lớn, ta nên tách thành nhiều interface nhỏ, với nhiều mục đích cụ
thể.
• Nguyên lý này rất dễ hiểu. Hãy tưởng tượng chúng ta có 1 interface lớn, khoảng 100 methods. Việc implements sẽ rất vất vả vì các class impliment interface này sẽ bắt buộc phải phải thực thi toàn bộ các method của interface. Ngoài ra còn có thể dư thừa vì 1 class không cần dùng hết 100 method. Khi tách interface ra thành nhiều interface nhỏ, gồm các method liên quan tới nhau, việc implement và quản lý sẽ dễ hơn.
Dependency inversion principle
1. Các module cấp cao không nên phụ thuộc vào các modules cấp thấp. Cả 2 nên phụ thuộc vào abstraction.
2. Interface (abstraction) không nên phụ thuộc vào chi tiết, mà ngược lại (Các class giao tiếp với nhau thông qua interface (abstraction), không phải thông qua implementation.)
• Có thể hiểu nguyên lí này như sau: những thành phần trong 1 chương trình chỉ nên phụ thuộc vào những cái trừu tượng (abstraction). Những thành phần trừu tượng không nên phụ thuộc vào các thành phần mang tính cụ thể mà nên ngược lại.
• Những cái trừu tượng (abstraction) là những cái ít thay đổi và biến động, nó tập hợp những đặc tính chung nhất của những cái cụ thể. Những cái cụ thể dù khác nhau thế nào đi nữa đều tuân theo các quy tắc chung mà cái trừu tượng đã định ra. Việc phụ thuộc vào cái trừu tượng sẽ giúp chương trình linh động và thích ứng tốt với các sự thay đổi diễn ra liên tục.
3. Tổng kết
SOLID là 5 nguyên tắc cơ bản trong việc thiết kế phần mềm. Nó giúp chúng ta tổ chức sắp xếp các function, method, class một cách chính xác hơn. Làm sao để kết nối các thành phần, module với nhau.
Rõ ràng, dễ hiểu
Teamwork là điều không thể tránh trong lập trình. Áp dụng SOLID vào công việc bạn sẽ tạo ra các hàm tốt, dễ hiểu hơn. Giúp cho bạn và đồng nghiệp đọc hiểu code của nhau tốt hơn.
Dễ thay đổi
SOLID giúp tạo ra các module, class rõ ràng, mạch lạc, mang tính độc lập cao. Do vậy khi có sự yêu cầu thay đổi, mở rộng từ khách hàng, ta cũng không tốn quá nhiều công sức để thực hiện việc thay đổi.
Tái sử dụng
SOLID khiến các lập trình viên suy nghĩ nhiều hơn về cách viết phần mềm, do vậy code viết ra sẽ mạch lạc, dễ hiểu, dễ sử dụng.