Các tầng trừu tượng trong lập trình
Một câu sáo rỗng: "Mọi thứ đều là trade-off". Trừu tượng hoá (abstraction) không là ngoại lệ. Cách phổ biến nhất trong OOP design là trừu tượng những thứ có thể đặt tên: "Tôi sẽ cần gửi một message, đẻ ra cái message service; ồ còn message factory; ồ còn message dispatcher; ồ thêm cái …; cứ thế tiếp …". Có khi nó work, có khi nó mang lại nhiều cái dở hơn cả giá trị nó tạo ra.
Mỗi abstraction là một canh bạc
Nếu bạn thắng, sẽ dễ và nhanh hơn để đặt các thay đổi tiếp lên trên nó.
Nếu bạn thua, bạn có một premature abstraction, và mọi thay đổi đặt lên trên đều có mùi. Và cuối cùng, khi có thêm các thay đổi đặt lên trên các thay đổi đó, nó sẽ giống ván Jenga mà ai cũng đoán được kết cục cuối.
Vậy nên abstraction không miễn phí. Cảm giác rất thoả mãn khi bạn có thể đặt tên cho mọi thứ và áp dụng được một design pattern vừa học. Nhưng nhớ rằng đó là cờ bạc, và thường thì xác suất nghiêng về phía thua. Phần mềm đã rối và phức tạp đến đâu, tỉ lệ thắng của bạn càng co lại.
Chi phí dễ hiểu
Một abstraction dù ngữ nghĩa và có ý nghĩa đến đâu, vẫn nhiều khả năng khó hiểu hơn một bản tương đương trực tiếp. Người đọc càng phải đi qua nhiều tầng trung gian, càng tốn tâm trí và nhận thức — đặc biệt là người khác, những người không chia sẻ cùng mức độ thân thuộc với kiến thức về cài đặt của bạn. Người khác ở đây có khi chính là bạn sau vài tháng.
Đó là điều K.I.S.S. nói đến: giữ mọi thứ ngu-ngốc-trực-tiếp, để ai cũng có thể Ctrl/Command+Click và mô phỏng được bước tiếp theo của runtime execution.
Nhớ rằng bạn luôn có thể quay lại refactor/abstract về sau nếu tính năng có lúc nào đó tiến hoá. Khi bạn cần refactor, khả năng cao là bạn đã hiểu sâu hơn vì đã trải qua một số "reality check" với code hiện tại. Refactor/khái quát hoá một đoạn code chuyên biệt luôn dễ hơn làm theo chiều ngược lại — sửa một đoạn code over-engineered/abstracted với những dependent đã xây sẵn lên trên.
Hãy hình dung codebase như một thực thể sống. Nó có vòng đời và cách tiến hoá riêng. Nó không phải là sản phẩm bạn giao một-lần-cho-xong. Hãy ghi nhớ điều đó﹣rằng luôn có rủi ro abstraction sai và chi phí dễ hiểu﹣khi biện minh các quyết định trong thiết kế, cài đặt (của bạn hay của người khác), và khi review code.
Đọc thêm
https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction
Lấy cảm hứng và hiện đang phản chiếu ý nghĩ từ huylenq.github.io. Các ghi chú thuộc về anh ấy; bản mirror này riêng tư và có ghi nguồn.