S.O.L.I.D là một bộ các nguyên tắc được đặt ra để đảm bảo cho code của bạn Clear and Ease of use, Reusability, Decoupling, Testablility, Modyfing/ Extending. Mình xin nói trước việc apply SOLID nó khiến code dài hơn, flow rắc rối hơn, debug sẽ mệt hơn. Nhưng xét tổng thể thì những ưu điểm của SOLID ăn đứt các khuyết điểm nhỏ lẻ. Nên các design pattern được suy luận và sinh ra từ nguyên lý SOLID. Việc hình thành nên các Design Pattern được phát triển qua các bước sau:
+ Các tiêu chí code ở trên
+ SOLID
+ Design pattern.
S.O.L.I.D gồm 5 nguyên lý tương ứng với 5 chữ cái
a. Single Responsibility Principle (SRP)
b. Open Close Principle (OCP)
c. Liskov Subsitution Principle (LSP)
d. Interface Segregation Principle (ISP)
e. Dependancy Inversion Principle (DIP)
5 nguyên lý này sẽ bám chặt vào tính các đặc trưng và trừu tượng của phong cách lập trình hướng đối tượng (OOP).
a. Nội dung và nguyên nhân sử dụng
a.1. Nội dung nguyên lý
A class should have only one reason to change.
Nhìn chung, thì từ class mang ý nghĩa tổng quát. Khi tạo class hoặc module hoặc function, chúng chỉ nên có một nhiệm vụ.
a.2. Nguyên nhân sử dụng
Quay lại một trong những nguyên tắc khi code Decoupling. Nếu class đảm nhận quá nhiều chức năng, thì khả năng chúng kết dính (lồng) với nhau khá cao, và khi có bất kì thay đổi nào liên quan đến một chức năng nhỏ trong đó, bạn sẽ phải test lại toàn bộ cái class đó, thậm chí là những phần liên quan đến class đó. Do đó, SRP ra đời.
b. Áp dụng
b.1 Đặt vấn đề
Bài toán đặt ra là fetchData from Server và parse data lên UI ở ViewController. Mình giả lập tạo một ViewController ở Playground như sau:
Và trong ViewControllerA ta code như sau:
Class trên đã vi phạm SRP như sau:
+ ViewControllerA phải thực hiện các function liên quan đến UI (viewDidLoad, viewWillAppear,v..v..)
+ ViewControllerA thực hiện việc handle với server, rồi lấy data update lên UI.
Giả sử bạn chưa thấy ảnh hưởng gì, nên bạn làm tương tự với ViewControllerB, ViewControllerC.
Vấn đề đặt ra như sau, nếu có bất kì sự thay đổi trong việc call Request (update từ Client hay backend fix bug thêm params) hoặc bất kì sự thay đổi ở Repsonse (thay đổi Object, hoặc type XML thay cho Json) thì bạn phải vào từng ViewController sửa lại code.
b.2 Áp dụng
Cơ bản thì ta phải tách ra việc handle với server về thành 1 class riêng, để đảm bảo mỗi người (class) một việc như sau:
Như vậy thì bây giờ, mọi thay đổi ở phần request hay response đều được xử lý ở class riêng và rõ ràng ViewController không bị ảnh hưởng gì hết. (Ở đây mình giả sử việc handleDataRepsonse bao gồm luôn việc decode thành Object Local luôn). ViewController sẽ luôn nhận được Object mà nó cần.
Ngoài ra, bên trong NetworkService vẫn đang giữ 2 việc xử lý request và response. Nếu đảm bảo đúng quy tắc thì phải chia ra RequestService và ResponseService. Đoạn này mình không đề cập thêm.
Mình chỉ muốn thảo luận 1 chút là đôi khi mình nghĩ cũng tuỳ từng huống, dự án mà có nên tuân thủ nguyên tắc này hay không. Vì như ví dụ trên NetworkService giữ 2 việc xử lý request và response vẫn đáp ứng được yêu cầu và tính ổn định. Nói chung tuỳ ngữ cảnh.