Trong bài trước SOLID – Tổng quan, tôi đưa ra quan điểm rằng SOLID không nhằm tạo ra những dòng code bất tử mà nhằm tạo ra những dòng code sẵn sàng thay đổi. Có thể cái tên SOLID khiến ta có chút liên tưởng ngược lại, nhưng từng nguyên tắc trong đó lại toàn nói về sự thay đổi.
Single Responsibility – không có nhiều hơn một lý do để thay đổi class
Ngay cái định nghĩa đã có từ thay đổi. Bạn viết một class và bạn phải đặt ra câu hỏi “NẾU CẦN THAY ĐỔI THÌ LÀM SAO”. Hãy chuẩn bị cho một tương lai không chắc chắn. Viết ra mọi thứ đơn nhiệm và bạn sẽ tối thiếu hóa xung đột sau này khi những yêu cầu sửa đổi, mở rộng được thêm vào. Việc sửa đổi ở class A sẽ không biến thành một vụ rút dây động rừng. Sửa ở A không kéo theo việc sửa ở B vì A và B là những class đơn nhiệm. Bạn không viết ra 2 class để làm cùng 1 nhiệm vụ đúng không?
Nguyên tắc đầu này nhắc nhở bạn hãy luôn sẵn sàng cho việc thay đổi.
Open/Closed: thiết kế để sẵn sàng mở rộng chứ không sửa đổi
Mở rộng hay sửa đổi thì cũng đều là thay đổi cả. Nguyên tắc này hướng dẫn bạn cách thay đổi cho đúng. Tôi nhét từ thiết kế vào bởi vì, “mở rộng không sửa đổi” không phải chỉ là quy tắc làm việc. Cố gắng không thay đổi những gì đã chạy là tốt, nhưng thiết kế mã nguồn không cho phép mở rộng thì bạn cũng chẳng làm gì được. Khi chắp bút cho một chức năng, hãy chuẩn bị luôn con đường để thay đổi nó trong tương lai, hãy thiết kế nó.
Liskov substitution: con phải kế tục được cha
Đầy sự thay đổi trong nguyên tắc này. Một thực tế trong lập trình, các bạn sẽ thực thi những lớp con cháu chứ không phải lớp cha. Nhưng khi khai báo lớp cha, các bạn vốn không biết trước các lớp con cháu sẽ như thế nào. Thực ra các bạn không quan tâm các lớp con cháu sẽ như thế nào. Nó có gen của lớp cha là được. Viết code để sự thay đổi là an toàn.
Interface segregation: tôi sẽ không phải phụ thuộc vào những hành vi mà tôi không sử dụng
Nguyên tắc này cũng hướng dẫn chúng ta đến sự thay đổi an toàn. Việc gì xảy ra khi tôi phải phụ thuộc vào thứ không liên quan tới tôi? Có nghĩa là một ngày đẹp trời tôi ngập trong rắc rối mặc dù tôi chẳng làm gì cả.
Dependency Inversion: không phụ thuộc vào code thực thi, mà là các khai báo trừu tượng
Bạn sẽ toát mồ hôi hột khi thay đổi một phụ thuộc cứng. Điều tồi tệ là dù có làm được, bạn cũng không chắc chắn về kết quả, công sức bỏ ra thì nhiều khi bạn phải code lại kha khá. Việc trừu tượng hóa vấn đề giống như bạn mua bảo hiểm vậy, vô dụng cho hiện tại, nhưng là cái phao cứu sinh khi rủi ro và là của để dành sau này.
Lời thú tội ở đây: tôi chỉ đang cố gắng thuyết phục, nhồi nhét vào đầu các bạn 2 chữ thay đổi. Viết code không phải là xây dựng những tượng đài trường tồn với thời gian. Mã nguồn SOLID hóa ra lại phải LIQUID. À thực ra là những nguyên tắc SOLID để có mã nguồn LIQUID. Những nguyên tắc này xoay quanh những mệnh đề: Nó sẽ thay đổi – Tại sao lại thay đổi – Thay đổi thành cái gì – Thay đổi như thế nào (thời trang hơn thì là thế này: WHEN it changes – WHY it change – WHAT it change to be – HOW it change). Nếu bạn có hai chữ “thay đổi” trong não, SOLID sẽ đến với bạn chứ không phải bạn chạy theo SOLID.
Các bài tiếp theo, chúng ta sẽ bàn bạc từng nguyên tắc một.