Nguyễn Đình Cường
0 comment
09 Nov, 2026
Gần như mọi lập trình viên đều sẽ gặp code legacy: hệ thống chạy lâu năm, ít tài liệu, không có test, ai cũng sợ động vào. Cám dỗ lớn nhất là viết lại từ đầu, nhưng thường đó là con đường rủi ro và tốn kém. Bài này giới thiệu cách tiếp cận thực tế hơn: dựng lưới an toàn bằng characterization test rồi cải thiện từng bước nhỏ.
Có một định nghĩa thực dụng: code legacy là code không có test, nên bạn không thể thay đổi nó một cách tự tin. Tuổi đời hay công nghệ cũ không phải điều quyết định. Chính thiếu lưới an toàn khiến mọi chỉnh sửa trở nên đáng sợ.
Cải thiện dần dần theo từng phần thường an toàn và mang lại giá trị sớm hơn. Dĩ nhiên có trường hợp phải thay thế hẳn, nhưng nên làm từng phần có kiểm soát.
Đây là loại test ghi lại hành vi hiện tại của code, dù hành vi đó đúng hay sai. Mục tiêu không phải xác minh tính đúng đắn mà là cho bạn biết khi nào mình vô tình làm thay đổi hành vi. Nó là lưới an toàn để refactor.
null.// Hàm cũ, ít ai hiểu rõfunction calcShipping(weight, zone, isMember) {var fee = 0;if (zone == 1) fee = 20000;else if (zone == 2) fee = 35000;else fee = 50000;if (weight > 5) fee += (weight - 5) * 4000;if (isMember) fee = fee * 0.9;return Math.round(fee);}// Characterization test: ghi lại hành vi quan sát đượctest('khu vực 1, 3kg, không thành viên', () => {expect(calcShipping(3, 1, false)).toBe(20000);});test('khu vực 2, 8kg, thành viên', () => {expect(calcShipping(8, 2, true)).toBe(42300);});test('khu vực không xác định rơi vào mức cao nhất', () => {expect(calcShipping(1, 99, false)).toBe(50000);});test('đúng ngưỡng 5kg không tính phụ phí', () => {expect(calcShipping(5, 1, false)).toBe(20000);});Có test này, bạn có thể refactor hàm sang cách viết sạch hơn (dùng bảng tra cứu cho phí khu vực, hằng số có tên...) và chạy lại để chắc hành vi giữ nguyên. Nếu phát hiện hành vi hiện tại là lỗi, hãy ghi chú lại và quyết định sửa riêng sau khi có sự đồng ý, vì nghiệp vụ có thể đang phụ thuộc vào đó.
Code legacy thường gọi trực tiếp database, file, mạng hoặc dùng biến toàn cục, nên khó đưa vào test. Cách xử lý là tạo những điểm cho phép thay thế phần phụ thuộc mà không đổi hành vi:
Đừng phán xét người viết trước. Họ đã làm việc với yêu cầu, hạn chót và hiểu biết tại thời điểm đó. Hãy coi đây là cơ hội học hỏi: nhìn thấy hậu quả thực tế của các lựa chọn thiết kế là bài học rất quý. Và hãy chia sẻ kiến thức bạn khám phá được bằng tài liệu hoặc test, để người sau không phải bắt đầu từ con số không.
Thay vì sợ hay viết lại tất cả, hãy bắt đầu từ việc ghi lại hành vi hiện tại bằng characterization test, rồi cải thiện từng bước nhỏ có lưới an toàn. Cách làm này vừa thực tế vừa giúp bạn hiểu sâu hệ thống.
Nếu bạn muốn rèn kỹ năng đọc, kiểm thử và cải thiện code qua các bài thực hành, hãy tham khảo các khóa học tại codebem.com.
Nguyễn Đình Cường
0 comment