Technical debt (nợ kĩ thuật) là gì? Làm gì để giải quyết "món nợ" này?
Nợ kĩ thuật được hiểu nôm na là khối lượng công việc còn lại (cần được giải quyết) trong một dự án công nghệ.
Mình tạm dịch technical debt là nợ kĩ thuật vì mình chưa tìm được cụm từ tương đương trong Tiếng Việt. :thinking:
Nếu là nợ thì ta có thể cân đo/đong đếm nó không?
Khi nói về "nợ", bạn sẽ nghĩ ngay rằng đấy là một thứ có thể được "định lượng", ví dụ: nợ đồng nghiệp 500k, nợ người yêu 1 con gấu bông, nợ bạn thân 1 ly cafe. Tuy nhiên, đối với nợ kĩ thuật, đôi khi bạn khó có thể định lượng được rằng món nợ là "bao nhiêu" vì việc này còn phụ thuộc rất nhiều vào định nghĩa của "nợ kĩ thuật" trong suy nghĩ của từng lập trình viên thuộc dự án.
Vậy nợ kĩ thuật được hình thành như thế nào? Nó tồn tại như thế nào trong một dự án công nghệ?
Xuyên suốt quá trình phát triển dự án, mọi quyết định kĩ thuật đều đi kèm "một món nợ kĩ thuật" nhất định.
Với các dự án dù là công nghệ hay bất kì lĩnh vực nào thì cũng cần phải có hạn chót (deadline) cho mọi công việc. Deadline sẽ giúp đảm bảo dự án phát triển ổn định, đúng thời hạn và còn đảm bảo sự phối hợp tốt nhất giữa những thành viên trong dự án. Tuy nhiên, đôi khi những deadline được đặt ra không hoàn toàn phù hợp với khối lượng thời gian cần bỏ ra để hoàn thành một công việc cụ thể. Do đó, những lập trình viên sẽ phải có những thỏa hiệp nhất định, với bản thân và cả với đội công nghệ. Họ sẽ phải chấp nhận dùng những "giải pháp tạm thời" để cho ra sản phẩm "chạy được và ổn định" trong thời gian ngắn nhất và sau đó sẽ dành thời gian để cải tiến, nâng cấp thành những giải pháp hiệu quả, có thể tồn tại lâu dài hơn. Đây là cách mà nợ kĩ thuật "hình thành và tích lũy".
Nguồn: pixabay.com
Thông thường, cụm từ "kế hoạch trả nợ kĩ thuật" sẽ không xuất hiện trong bất kì một bản kế hoạch nào của dự án và những lập trình viên sẽ phải song song "trả nợ cũ" trong quá trình phát triển tính năng mới. Nếu bạn may mắn được tham gia trong một đội kĩ thuật (technical team) có người quản lí (technical leader) hiểu rõ và có thể cảm thông với bạn về "vấn đề nợ kĩ thuật", bạn sẽ có thời gian để "trả nợ" dưới sự bảo hộ của người quản lí ấy.
Vì sao mình lại dùm cụm từ "dưới sự bảo hộ" và vì sao lại cần "sự bảo hộ" ấy? Những thành viên trong dự án chịu trách nhiệm về mảng kinh doanh và vận hành nói chung (business và operation) thông thường sẽ không thích các lập trình viên dành thời gian "trả nợ kĩ thuật" vì, đối với họ, suy cho cùng việc làm ấy sẽ không tạo nên một tính năng mới hay thay đổi bất kì yếu tố giao diện nào. Họ sẽ đặt ra một câu hỏi: "Tại sao phải làm việc đấy khi mà nó không dẫn đến bất kì tính năng nào mới cho sản phẩm?". Nhưng thật ra những người làm business và operation cũng có lí do riêng của họ. :sigh:
Đối với trường hợp xấu nhất, nợ kĩ thuật sẽ tích lũy và lớn dần đến khi bạn "mất khả năng chi trả". Một ví dụ điển hình cho nợ kĩ thuật là khả năng mở rộng của sản phẩm (scalability of applications). Những quyết định ban đầu bạn lựa chọn để có thể cho ra một sản phẩm "chạy được" trong thời gian ngắn nhất chỉ phù hợp cho 1,000 người dùng (users) truy cập cùng 1 lúc. Tuy nhiên, để đáp ứng được 1,000,000 người dùng là một câu chuyện hoàn toàn khác. Những lập trình viên hiểu rõ rằng để đạt được điều đó, rất nhiều thời gian và công sức cần được bỏ ra, ví dụ như làm sao để giảm truy cập database, tạo những logic caching ra sao, ... Nhưng thời gian không cho phép họ thực hiện tất cả những công việc ấy và thế là họ mang trên vai một món nợ kĩ thuật khá lớn khi sản phẩm lớn dần.
*Đùa thôi*
Nói thêm một chút cụ thể về lập trình (mình sẽ cố gắng viết dễ hiểu để những bạn không làm công nghệ cũng có thể đọc và nắm được ý chính :P). Bản thân mình là một lập trình viên front-end và công nghệ mà mình sử dụng là React cho lập trình web.
Câu "bước trên ranh giới đúng/sai của việc thiết kế hệ thống" trên là mình tạm dịch từ câu "constantly walk on the thin line of architectural correctness" lấy từ bài blog7 architectural attributes of a reliable React component- một bài blog rất hay viết về cách thiết kế một React component (bạn nào làm về React thì nên đọc nhé).
Nguồn: https://dmitripavlutin.com
Giải quyết "món nợ" này như thế nào? Làm sao để hạn chế tạo ra nợ?
Đối với bất kì món nợ nào, giải quyết khi nợ chưa trở nên quá lớn (và dẫn đến việc mất khả năng chi trả) luôn luôn là cách tốt nhất. Mình sẽ tạm gọi quá trình "trả nợ" là "dọn code". Trong quá trình làm việc, bạn sẽ phải luôn để ý "dọn code" bất cứ khi nào "có thể" (có thể ở đây có nghĩa là bạn có đủ thời gian và kiến thức).
Dọn code thông thường sẽ bao gồm những hoạt động sau:
- Cải tiến code (refractor code): việc để "code xấu" tồn tại trong mã nguồn ứng dụng là không hề tốt. "Code xấu" có thể bị nhân bản bất kì lúc nào (duplicate). Lập trình viên mới xem xét code có sẵn để làm nền móng phát triển một tính năng mới sẽ tìm thấy code xấu và tái sử dụng nó, và thế là nợ kĩ thuật cho phần "code xấu" ấy nhân đôi!
- Viết lại code (rewrite code): nếu cải tiến code mà không giúp cải thiện được tình hình thì đó là lúc bạn phải xóa toàn bộ code cũ và thay bằng code mới. Tuy nhiên, viết lại code không phải luôn mang lại lợi ích nên bạn và mọi người trong team phải luôn cân nhắc/bàn bạc kĩ lưỡng trước khi đưa ra quyết định. Một trong những thời điểm để viết lại code phổ biến là viết lại khi bạn xây dựng một tính năng mới vì khi ấy bạn sẽ có đủ thời gian để đưa ra những quyết định chính xác hơn.
- Sử dụng giải phát mới tốt hơn, lâu bền hơn và tuân theo những quy tắc lập trình tốt hơn: code tốt thì sẽ có vòng đời lâu, có thể là vài năm nhưng "code xấu" thì phải được dành thời gian ra để nâng cấp. Lập trình viên luôn có thể ước lượng được "vòng đời" của một đoạn code mà họ viết ra. Họ là những người hiểu rõ nhất "đoạn code" ấy có thể tồn tại bao lâu và đến khi nào thì phải viết code mới. Tuy nhiên, những đoạn code tốt và tối ưu hơn thì chắc chắn cần nhiều thời gian để tạo ra. Do đó, nếu team thường xuyên phải chạy đua deadline thì bạn và đồng nghiệp nên định kỳ dành ra những khoảng thời gian để nâng cấp hệ thống hiện tại.
- Xóa những đoạn code không dùng tới
Bạn có thể dễ dàng nhận ra rằng nợ kĩ thuật hầu như là điều không thể tránh khỏi trong mọi dự án công nghệ. Tuy nhiên, nếu những thành viên trong dự án có tư duy nhất định về việc giải quyết và hạn chế nợ kĩ thuật thì việc "mất khả năng chi trả" là hoàn toàn có thể tránh khỏi. Đội kĩ thuật cần có những quy tắc được đề ra sẵn (coding conventions) để hạn chế tối đa những món nợ không mong muốn. Bên cạnh đó, bạn và đồng nghiệp có thể thực hiện những kế hoạch sau:
- Dành thời gian nghiên cứu những phương pháp và quy tắc lập trình tốt (best coding practices and conventions) để viết nên những tính năng chỉ để hỗ trợ cho việc phát triển sản phẩm (engineering-driven features), không phải là tính năng cho người dùng (end-user features).
- Duyệt code (code reviews) để góp ý và học tập lẫn nhau
---------------------------
Và đấy là tất cả những gì mình cảm nhận và đồng thời tham khảo từ một số nguồn khác nhau về nợ kĩ thuật - technical debt. Hãy bình luận bên dưới cho mình biết bạn đồng tình/không đồng tình với những ý nào trong bài viết trên và, nếu có thể, hãy chia sẻ với mình cách bạn và đồng nghiệp sử dụng để giải quyết và hạn chế nợ kĩ thuật nhé :)
Nguồn tham khảo thêm:
- Introduction to the Technical Debt Concept
- There are 3 main types of technical debt. Here’s how to manage them.
- Understanding technical debt
- Refactoring techniques
engineering
,technical practices
,vtcc_intern_6
,công nghệ thông tin
Bài viết giúp mình nhận ra rất nhiều "sạn" trong phong thái "code" của bản thân.
Cảm ơn bạn vì bài viết hữu ích.
Phạm Nguyễn Hoàng Lộc
Bài viết giúp mình nhận ra rất nhiều "sạn" trong phong thái "code" của bản thân.
Cảm ơn bạn vì bài viết hữu ích.