# Kinh nghiệm làm việc với Legacy Code
Hôm nay tôi muốn chia sẻ những bài học kinh nghiệm sau 6 tháng làm việc với một hệ thống legacy code lớn tại công ty - một thách thức mà hầu hết các developer đều phải đối mặt trong sự nghiệp.
## Thách thức ban đầu
Khi được giao nhiệm vụ bảo trì và nâng cấp hệ thống quản lý khách hàng có tuổi đời hơn 10 năm, tôi đã gặp phải những khó khăn sau:
- Không có tài liệu kỹ thuật hoặc tài liệu đã lỗi thời
- Code không có test, không có comment
- Sử dụng công nghệ cũ và nhiều thư viện không còn được hỗ trợ
- Kiến trúc phức tạp với nhiều dependency không rõ ràng
- Áp lực phải thêm tính năng mới mà không làm hỏng chức năng hiện có
## Chiến lược hiệu quả
### 1. Hiểu trước khi thay đổi
- Dành 2 tuần đầu chỉ để đọc code và ghi chú
- Vẽ sơ đồ hệ thống để hiểu luồng dữ liệu
- Nói chuyện với người dùng để hiểu cách họ sử dụng hệ thống
### 2. Xây dựng lưới an toàn
- Viết test cho các chức năng quan trọng trước khi thay đổi
- Tạo môi trường staging giống production
- Thiết lập quy trình rollback nhanh
### 3. Cải thiện từng phần nhỏ
- Áp dụng nguyên tắc "Boy Scout Rule": Luôn để lại code sạch hơn khi bạn tìm thấy nó
- Refactor từng phần nhỏ, không cố gắng sửa tất cả cùng lúc
- Tạo wiki cho team về cách hệ thống hoạt động và các "gotcha" và edge case
- Comment code phức tạp giải thích tại sao chứ không chỉ là gì
## Kết quả
Sau 6 tháng áp dụng chiến lược này:
- Thêm thành công 3 tính năng lớn mà không gây gián đoạn
- Giảm 60% thời gian deploy
- Tăng test coverage từ 0% lên 40%
- Giảm 70% số lượng bug báo cáo hàng tháng
- Tạo được tài liệu giúp onboard nhân viên mới nhanh hơn 3 lần
## Bài học kinh nghiệm
Kinh nghiệm này dạy tôi rằng làm việc với legacy code không phải là "thi đấu" như nhiều developer nghĩ. Với phương pháp đúng đắn, bạn có thể cải thiện hệ thống dần dần mà không cần viết lại từ đầu - một giải pháp thường rủi ro và tốn kém hơn nhiều người nghĩ.
Code Example
// Ví dụ về Adapter Pattern để tách biệt code mới và cũ // Interface mới interface ModernPaymentProcessor { processPayment(amount: number, currency: string): Promise<PaymentResult>; } // Adapter cho legacy code class LegacyPaymentAdapter implements ModernPaymentProcessor { private legacyProcessor = new LegacyPaymentSystem(); async processPayment(amount: number, currency: string): Promise<PaymentResult> { // Chuyển đổi tham số cho hệ thống cũ const legacyAmount = this.convertToLegacyFormat(amount, currency); // Gọi hệ thống cũ const result = this.legacyProcessor.makePayment(legacyAmount); // Chuyển đổi kết quả sang định dạng mới return this.convertToModernResult(result); } private convertToLegacyFormat(amount: number, currency: string): string { // Logic chuyển đổi return `${amount}|${currency}`; } private convertToModernResult(legacyResult: any): PaymentResult { // Logic chuyển đổi kết quả return { success: legacyResult.status === "OK", transactionId: legacyResult.id, timestamp: new Date() }; } }
Legacy CodeRefactoringBảo trì phần mềm