Không Có Giới Hạn Nào Cho Mức Độ Tệ Của Mã Nguồn
Bài viết phân tích sự khác biệt giữa ẩn dụ về 'con tàu đang chìm' và thực tế của mã nguồn kém chất lượng trong lĩnh vực công nghệ. Tác giả lập luận rằng phần mềm không có 'điểm sàn' hay 'sự phá sản' như các hệ thống vật lý hay tài chính, khiến cho nợ kỹ thuật có thể kéo dài vô hạn. Thay vì tìm kiếm lối thoát, các kỹ sư và doanh nghiệp cần chấp nhận thực tế này và chủ động nỗ lực duy trì chất lượng phần mềm mỗi ngày.
Không Có Giới Hạn Nào Cho Mức Độ Tệ Của Mã Nguồn
Bài viết này thách thức quan niệm phổ biến khi mô tả các codebase (mã nguồn) kém chất lượng như một "con tàu đang chìm", chỉ ra rằng ẩn dụ này sai lầm vì phần mềm không có điểm dừng hay sự sụp đổ vật lý. Thay vào đó, mã nguồn có thể trở nên tệ hơn vô hạn, và doanh nghiệp sẽ gục ngã trước khi mã nguồn chạm đến bất kỳ "tầng đáy" nào. Tác giả nhấn mạnh tầm quan trọng của việc thay đổi tư duy quản lý để tránh những quyết định sai lầm do ảo tưởng về một "sự khởi động lại" hay "viết lại toàn bộ".
Ẩn dụ "Con Tàu Đang Chìm" Gây Hiểu Lầm
Hơn một thập kỷ trước, tôi có trải nghiệm đầu tiên với một legacy codebase (mã nguồn kế thừa) xấu xí khi vừa gia nhập Amazon. Nhiệm vụ của nhóm tôi nghe có vẻ đơn giản: xử lý đơn hàng bằng cách ghi dữ liệu vào cơ sở dữ liệu và gọi các dịch vụ nội bộ khác. Chúng tôi ước tính chỉ cần khoảng hai chục kỹ sư giỏi là đủ để duy trì hệ thống này. Thế nhưng, tổ chức của chúng tôi có hàng trăm người, và hệ thống đã phình to đến mức không ai có thể hiểu hết cách nó vận hành.
Sự luân chuyển nhân sự thường xuyên khiến kiến thức về hệ thống bị mai một. Kết quả là mã nguồn chứa đầy những "nghĩa địa ma ám" – nơi không ai dám động vào vì sợ hãi và thiếu phần thưởng cho việc đơn giản hóa. Các quy tắc nghiệp vụ do những người đã rời đi từ lâu đặt ra, thường không được ghi chép ở bất kỳ đâu hoặc chỉ nằm trong những tài liệu lỗi thời. Khi có sự cố, hệ thống báo động (pager) sẽ nhắc nhở chúng tôi rằng ai đó trong mạng lưới phụ thuộc rối rắm đang không hài lòng. Nhờ cơ chế phản hồi này, hệ thống vẫn "nổi", nhưng cực kỳ khó thay đổi và có hiệu suất tồi tệ. Dù vậy, các lớp chức năng mới vẫn liên tục được thêm vào để hỗ trợ sản phẩm mới của Amazon.
Những nỗ lực tái cấu trúc (re-architecture) cũng luôn thất bại. Một quản lý hoặc kỹ sư cao cấp mới sẽ đến, nhận ra "mọi thứ đang tệ", và đề xuất sửa chữa. Tuy nhiên, do không có sẵn kỹ sư, họ lại tuyển thêm người. Vòng lặp này lặp lại: thiết kế vội vàng dựa trên thông tin không đầy đủ, tham vọng thăng tiến cá nhân, và cuối cùng là một mớ "bản vá" được gắn vĩnh viễn vào kiến trúc cũ. Kỹ sư trưởng sau khi hoàn thành mục tiêu thăng tiến sẽ rời đi, còn biên chế thì tăng lên vì kế hoạch di dời quá phức tạp để hoàn thành. Con tàu chìm dường như không có hồi kết.
Điểm Kết Thúc Nằm Ở Đâu?
Khoảng ba năm sau khi tôi rời đi, một đồng nghiệp cũ đã gọi điện và hỏi tôi: "Rồi nó sẽ kết thúc ở đâu? Làm sao nó kết thúc?" Câu hỏi này khiến tôi nhận ra chúng ta đang nhầm lẫn giữa mã nguồn và doanh nghiệp.
Một doanh nghiệp có thể "chìm". Phần mềm tồi là gánh nặng thực sự, nhưng mức độ ảnh hưởng phụ thuộc vào nhiều yếu tố. Với một công ty có dòng tiền dồi dào như Amazon, họ có thể chịu đựng một thời gian trước khi nó ảnh hưởng đến lợi nhuận. Với các công ty nhạy cảm hơn với chất lượng phần mềm, nó có thể là lời mời gọi đối thủ cạnh tranh khai thác. Nhưng đối với mã nguồn, sự "chìm" không bao giờ kết thúc. Nó là một con tàu chìm vô hạn, bởi vì không có giới hạn nào cho sự tệ hại của mã. Mã nguồn không giống như một tòa nhà hay cây cầu – nếu cứ xây thêm tầng và phòng mãi, nó sẽ sụp đổ. Phần mềm không có ràng buộc như vậy. Mã nguồn luôn có thể tệ hơn, luôn có thể thêm một lớp gián tiếp hoặc giảm hiệu suất.
Một số người có thể phản biện rằng phần mềm có thể hoàn toàn ngừng hoạt động nếu tệ đến mức nào đó. Nhưng trong thực tế, những thay đổi gây hỏng hóc sẽ nhanh chóng bị revert (khôi phục), còn hàng nghìn thay đổi trước đó làm cho mã nguồn tệ hơn thì không. Phần mềm vẫn tiếp tục "hoạt động" trong trạng thái đó. Trong các trường hợp khác, chi phí tăng vọt của mã nguồn tồi sẽ vượt qua lợi ích của nó, hoặc tốc độ phát triển tiến về con số không vì không thể phát hành thứ gì mới mà không gây ra sự cố. Trong mọi tình huống, chính doanh nghiệp sẽ chết trước khi mã nguồn chạm đến bất kỳ "tầng đáy" giả định nào. Vì vậy, đừng hành động như thể có một tầng đáy như vậy!
Nợ Kỹ Thuật Không Có "Phá Sản"
Sự kìm hãm của phần mềm tồi đối với doanh nghiệp là mối đe dọa thực sự, và đó là lý do các tổ chức tốt chú trọng chất lượng mã nguồn. Vì không có ngưỡng thất bại đột ngột, nó thường được gọi là "technical debt" (nợ kỹ thuật). Ẩn dụ này tốt hơn (nợ có thể cộng dồn vô hạn), nhưng vẫn không hoàn hảo. Nợ có điểm "kết thúc" vì phá sản là một sự thiết lập lại cưỡng bức, tương đương trong phần mềm là viết lại toàn bộ – một lựa chọn hiếm khi khả thi.
Lựa chọn gần nhất cho một tập đoàn như Amazon là tôi gọi là "kênh phụ" (side-channel): tách một nhóm để xây dựng một hệ thống mới, hoàn toàn tách biệt với tối thiểu các tính năng cần thiết cho một trường hợp sử dụng mới. Nhưng hệ thống cũ vẫn phải được duy trì vì tất cả các trường hợp sử dụng cũ vẫn tồn tại. Điều này không giống như "xoá sạch" trong phá sản.
Những mô hình tư duy sai lầm về phần mềm dẫn đến quyết định sai lầm. Nếu nghĩ rằng có một "nút reset cứng", việc trì hoãn nợ kỹ thuật có vẻ không đáng lo. Niềm tin rằng một lần viết lại sắp tới sẽ sửa chữa mọi thứ dẫn đến những quyết định tồi tệ hơn hôm nay, bởi vì người ra quyết định không hiểu rằng không có lối thoát nào cả.
Các ẩn dụ như "tòa nhà sụp đổ" hay "con tàu chìm" không phù hợp với phần mềm, nhưng chúng ta có thể chấp nhận chúng để nhấn mạnh điều làm phần mềm khác biệt. Tòa nhà đang sụp đổ vô hạn. Con tàu đang chìm vô hạn. Không có ràng buộc tự nhiên nào sẽ đánh thức quản lý dự án của bạn và buộc họ phải giải quyết nợ kỹ thuật. Phần mềm chỉ có thể duy trì chất lượng cao nếu chúng ta thực sự nỗ lực để ngăn chặn sự chìm xuống. Hãy cầm lấy chiếc xô và bắt đầu múc nước.