SOLID là viết tắt của 5 tính chất được coi là 5 nguyên tắc “vàng” trong lập trình hướng đối tượng. Ở bài viết này chúng ta sẽ đi tìm hiểu xem 5 nguyên tắc đó là gì mà được mệnh danh là nguyên tắc vàng và cách chúng ta ứng dụng chúng vào lập trình.
SOLID là tên viết tắt của 5 nguyên lý hợp thành lại bao gồm:
- Single responsibility principle
- Open/closed principle
- Liskov substitution principle
- Interface segregation principle
- Dependency inversion principle
1. Single responsibility principle:

Nguyên lý đầu tiên, tương ứng với chữ S trong SOLID. Nội dung nguyên lý:
– Một class chỉ nên giữ 1 trách nhiệm duy nhất (Nghĩa là chỉ có thể sửa đổi class đó với 1 lý do duy nhất).
Khi một class có quá nhiều chức năng, nó sẽ trở lên cồng kềnh và phức tạp. Nếu yêu cầu bài toán thay đổi thì đồng nghĩa với việc phải thay đổi lại code. Nó sẽ trở lên khó khăn, mất thời gian và công sức. Cùng nhìn vào ví dụ bên dưới :

ví dụ class doWork cần thực hiện logic của 4 function là A, B, C và D.
chỉ cần logic của 1 trong 4 hàm thay đổi thì class doWork sẽ phải sửa lại. Theo đúng nguyên lý thì chúng ta nên tách ra làm 4 class riêng. Mỗi class xử lý logic riêng biệt, vì vậy nếu có thay đổi ở 1 trong 4 class trên thì các class còn lại sẽ không bị ảnh hưởng. Nó sẽ dễ dàng hơn trong việc sửa chữa, nâng cấp hay quản lý.

2. Open/closed principle:

Nguyên lý thứ hai, tương ứng với chữ O trong SOLID. Có nội dung như sau:
Có thể thoái mái mở rộng 1 class, nhưng không được sửa đổi bên trong class đó (open for extension but closed for modification).
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ũ) không nên sửa đổi class cũ. Ví dụ :

Dễ thấy nếu trong tương lại ta thêm nhiều class nữa, muốn tính diện tích của nó ta lại phải sửa class Geometry, viết thêm chừng đó hàm if nữa. Sau khi chỉnh sửa, ta phải compile và deploy lại class Geometry.
Sau khi chỉnh sửa lại như sau:

3. Liskov Substitution Principle

Nguyên lý thứ ba, tương ứng với chữ L trong SOLID. Nội dung nguyên lý:
Trong một chương trình, các object của class con có thể thay thế class cha mà không làm thay đổi tính đúng đắn của chương trình.
Đến nguyên lý thứ 3 này có chút hơi khó hiểu, nhưng không sao. Hãy thử tưởng tượng bạn có 1 class cha là Vịt. Các class VịtBầu, VịtXiêm, VịtCỏ có thể kế thừa class này, các class này sẽ chạy bình thường. Tuy nhiên nếu ta viết class VịtChạyPin, cần pin mới chạy được. Khi class này kế thừa class Vịt, vì không có pin không chạy được, sẽ gây lỗi. Đó là 1 trường hợp vi phạm nguyên lý này. Đến đây bạn đã hình dung và hiểu được phần nào về nguyên lý thứ 3 này chưa. Đơn giản hơn là khi các class con kế thừa từ class cha, nó phải sở hữu những đặc điểm chung và bắt buộc của lớp cha. Bạn là con của bố bạn và đương nhiên bạn không thể mang họ ông hàng xóm và có vẻ ngoài giống đến 90% ông ấy được phải không nào 😀
4. Interface Segregation Principle.

Nguyên lý thứ tư, tương ứng với chữ I trong SOLID. Nội dung nguyên lý:
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 khá dễ hiểu. Hãy tưởng tượng chúng ta có 1 interface lớn, khoảng 100 methods. Và đương nhiên bất kì class nào implements từ interface đó thì chúng cũng phải implements hết 100 methods đó. Việc này sẽ gây rất nhiều khó khăn cho người lập trình viên và dẫn đến việc dư thừa không cần thiết. 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, tiết kiệm thời gian.
5. Dependency inversion principle.

Nguyên lý cuối cùng, tương ứng với chữ D trong SOLID. Nội dung nguyên lý:
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, không phải thông qua implementation.)
Nguyên lý này khá lắt léo, mình sẽ lấy ví dụ thực tế. Chúng ta đều biết 2 loại đèn: đèn tròn và đèn huỳnh quang. Chúng cùng có đuôi tròn, do đó ta có thể thay thế đèn tròn bằng đèn huỳnh quanh cho nhau 1 cách dễ dàng.

Ở đây, interface chính là đuôi tròn, implementation là bóng đèn tròn và bóng đèn huỳnh quang. Ta có thể swap dễ dàng giữa 2 loại bóng vì ổ điện chỉ quan tâm tới interface (đuôi tròn), không quan tâm tới implementation.
Trong code cũng vậy, khi áp dụng Dependency Inverse, ta chỉ cần quan tâm tới interface. Để kết nối tới database, ta chỉ cần gọi hàm Get, Save … của Interface IDataAccess. Khi thay database, ta chỉ cần thay implementation của interface này.
Mình nói khá kĩ về nguyên lí này vì nó khá quan trọng. Về sau mình sẽ viết 1 bài riêng về Dependency Injection (Dependency Injection chỉ là 1 trong những pattern để hiện thực Dependency Inversion, Dependency Injection != Dependency Inversion nhé các bạn)/
Bài viết khá dài, xin có lời khen với các bạn đã kiên nhẫn đọc hết. Ở những bài viết sau mình sẽ giải thích rõ hơn về từng nguyên lý SOLID này, cùng với code mình họa + cách áp dụng nguyên lí vào quá trình code.
Link tham khảo: http://blogs.msdn.com/b/cdndevs/archive/2009/07/15/the-solid-principles-explained-with-motivational-posters.aspx