Refactoring (tái cấu trúc) or rewrite (viết lại)?
July 6, 2024Refactoring or rewrite?
Đây luôn luôn là câu chuyện dài mà tất cả công ty và lập trình viên trong một tổ chức đều thảo luận hằng ngày. Có lẽ câu nói thường gặp nhất trong nhóm phần mềm là: “Viết lại (cái này) chỉ mất mấy ngày thôi, sửa thì không biết bao giờ mới xong”. Và điều gì xảy ra khi lập trình viên được bật đèn xanh để viết lại? 70% sẽ là vũng lầy trong vài tuần kế tiếp trước khi quay trở lại vạch xuất phát với phương án sửa. 20% may mắn hơn thì chạy được nhưng không ổn định. 10% hoạt động hoàn hảo, những đoạn code tuyệt vời sẽ lại nhận câu tương tự vào năm sau: “viết lại (cái này) chỉ mất mấy ngày thôi, sửa thì không biết bao giờ mới xong”.
Có hai lý do để những câu chuyện này vẫn luôn lặp lại.
Thứ nhất, “cỏ nhà hàng xóm luôn xanh hơn và code lập trình viên khác luôn bẩn hơn”. Nói chung, mọi lập trình viên dù ở trình độ nào cũng đều không thích code của lập trình viên khác. Hãy tưởng tượng, một lập trình viên khởi tạo object ở mọi nơi sẽ tạo ra những đoạn code khiến một lập trình viên khác thấy khó chịu và anh ta thấy rằng nên sử dụng pattern Dependency Injection thì sẽ tốt hơn. Nhưng lập trình viên khác đọc vào những đoạn code có Dependency Injection lại thấy thật không tường minh và khó hiểu. Lập trình viên khác lại muốn sử dụng pattern Factory cho trường hợp này. Thậm chí, bạn còn không hài lòng về code mình viết ra chứ đừng nói đến code của lập trình viên khác bởi đơn giản, nếu bạn luôn hài lòng với code của mình, điều đó cho thấy bạn không có sự phát triển về chuyên môn.
Thứ hai, lập trình viên đến và đi nhưng code của họ thì ở lại. Do đó, lập trình viên liên tục phải làm việc với code của những lập trình viên khác. Thậm chí, trên những code mình không thực sự hiểu rõ. Vậy nên viết lại luôn là lựa chọn đầu tiên. Dễ hiểu vì đó là giải pháp đơn giản cho chính họ.
Nhưng chậm một chút, bạn có biết việc viết lại thường không mang lại hiệu quả cao? Ít nhất bởi ba lý do:
Thứ nhất, việc viết lại thường không đơn giản như bạn nghĩ ban đầu. Nói chung, lập trình viên chỉ dành khoảng 20% thời gian để hoàn thành những tình huống cơ bản (happy case), 80% thời gian còn lại để xử lý những trường hợp đặc biệt, những tình huống exception – đây thường là những điều bị bỏ qua khi ước lượng. Nên trong thực tế, nếu lập trình viên nói rằng “cần vài ngày” để viết lại, toàn bộ công việc có thể mất đến vài tuần để hoàn chỉnh. Chưa kể, việc viết lại có thể bỏ sót những tình huống exception.
Thứ hai, phần mềm luôn thay đổi và đó cũng chính là nơi phát sinh ra những tình huống exception – những đoạn code khó hiểu. Nếu lập trình viên không hiểu toàn bộ lịch sử và tầm nhìn về tương lai của chức năng, họ có thể đi vào vết xe đổ của những người đi trước. Hãy nhớ rằng, những lập trình viên trước, họ cũng đã dành rất nhiều thời gian để hiệu chỉnh code phù hợp với chức năng hiện có.
Thứ ba, đối với những dòng code của lập trình viên này có thể những gì họ code của ngày hôm nay nhưng ngày mai thì lại không phù hợp nữa đối với lập trình viên khác. Hai lập trình viên cũ và mới thì lại không biết nhau, không biết về tư duy, trình độ và cách tiếp cận của nhau nên rất khó có thể hiệu quả khi viết mới
Netscape là một ví dụ kinh điển trong tình huống này. Vào những năm 1990, Netscape là trình duyệt phổ biến nhất, ổn định và mạnh mẽ. Sau thành công vang dội, Netscape đứng trước quyết định lịch sử: viết lại toàn bộ sản phẩm. Họ ước tính mất 1 năm để hoàn thành phiên bản mới, thực tế đã mất tới 3 năm. Trong 3 năm đó, thị phần dần rơi vào tay các đối thủ do Netscape không có những cải tiến trên phiên bản hiện tại. Đau đớn hơn, phiên bản mới, sau khi được viết lại là nỗi kinh hoàng – nó hoàn toàn không ổn định. Những gì tạo nên tên tuổi Netscape bị đánh mất, sản phẩm đi vào dĩ vãng.
Tôi hiểu, sẽ luôn có những tình huống cho việc viết lại trở thành một quyết định đúng đắn. Đặc biệt khi bạn đã sai lầm ngay từ những dòng code đầu tiên; hay sự giới hạn về công nghệ, nền tảng phía dưới; hoặc đạt tới giới hạn về hiệu năng, khả năng mở rộng,… Hãy chắc chắn về việc kiểm chứng giới hạn. Khi lập trình viên đã có lý do cụ thể cho giới hạn, viết lại là cách duy nhất để giải quyết nỗi đau.
May mắn là luôn có cách để nỗi đau không trở nên quá lớn bằng cách triệt tiêu chứng từ từ qua việc liên tục cải tiến code, liên tục refactoring từng phần, từng phần một.
Nguồn: Rewrite từ cuốn DevUP
—