Nếu bạn vừa tiếp quản một codebase C++ hiện có thì nên làm gì?
- Khi bắt đầu công việc mới, chuyển nhóm, hoặc sau khi một đồng nghiệp giàu kinh nghiệm rời đi, bạn có thể phải phụ trách một codebase C++ lớn với cấu trúc phức tạp và khác biệt.
- Bạn cần sửa lỗi và bổ sung tính năng mới, nhưng không thể phớt lờ hay xóa bỏ codebase đó. Nó quan trọng với người trả lương cho bạn, nên cũng quan trọng với bạn.
Bước đầu tiên: làm cho mã chạy được trên máy local
- Chỉ thực hiện các thay đổi tối thiểu đối với mã và hệ thống build để nó chạy được trên máy local. Chưa vội refactor quy mô lớn.
Loại bỏ những thứ không cần thiết
- Loại bỏ mọi thứ không tuyệt đối cần thiết để cung cấp các tính năng mà công ty hoặc dự án mã nguồn mở đang quảng bá và bán ra.
Đưa dự án lên thế kỷ 21
- Thêm CI (tích hợp liên tục), linter, fuzzing, tự động định dạng mã, v.v.
Cải thiện mã theo từng bước nhỏ
- Thực hiện các thay đổi nhỏ và dần dần đối với mã. Lặp lại việc này để đưa dự án về trạng thái chấp nhận được về bảo mật, trải nghiệm lập trình viên, độ chính xác và hiệu năng của ứng dụng.
Cân nhắc viết lại một phần bằng ngôn ngữ an toàn bộ nhớ
- Nếu có thể, hãy cân nhắc viết lại một phần mã bằng ngôn ngữ an toàn bộ nhớ.
Xác định rõ các nền tảng được hỗ trợ
- Ghi rõ trong README các cặp <kiến trúc>-<hệ điều hành> được hỗ trợ chính thức. Ví dụ như x86_64-linux hoặc aarch64-darwin.
Làm cho việc build chạy được trên máy
- Đảm bảo có thể build một cách đáng tin cậy và nhất quán trên tất cả các nền tảng được hỗ trợ.
Làm cho test chạy qua trên máy
- Nếu chưa có test, hãy viết test trước khi thay đổi mã, rồi quay lại sau khi test đã chạy qua.
Mô tả cách build và test ứng dụng trong README
- Đơn giản hóa các lệnh build và test để cả người không chuyên cũng có thể dễ dàng làm theo.
Tìm những "quả thấp dễ hái" để tăng tốc build và test
- Tìm những cách đơn giản để tăng tốc build và test mà không cần thay đổi hệ thống build.
Xóa mã không cần thiết
- Dùng cảnh báo của compiler và linter để tìm và loại bỏ mã không được sử dụng.
Linter
- Không sa đà quá mức vào các quy tắc linter; chỉ thêm một vài quy tắc cơ bản và tích hợp chúng vào chu kỳ phát triển.
Định dạng mã
- Vào thời điểm phù hợp, áp dụng hàng loạt một phong cách mã thống nhất cho toàn bộ codebase và commit cấu hình.
Sanitizer
- Sử dụng sanitizer để phát hiện và sửa các bug thực tế cùng rò rỉ bộ nhớ.
Thêm pipeline CI
- Tự động hóa tất cả các điểm tốt đã thiết lập (linter, định dạng mã, test, v.v.) và tạo binary cho môi trường production với mọi thay đổi.
Cải thiện mã theo từng bước nhỏ
- Tập trung vào các mục tiêu cụ thể như bảo mật, độ chính xác và hiệu năng, thay vì các tiêu chí mang tính chủ quan như "clean code".
Viết lại bằng ngôn ngữ an toàn bộ nhớ?
- Đây là công việc đang được bàn luận, với rất nhiều lưu ý. Chỉ nên làm khi có lý do rõ ràng.
Kết luận
- Cung cấp một kế hoạch cụ thể theo từng bước để thoát khỏi tình trạng của một codebase C++ legacy phức tạp.
Phụ lục: quản lý phụ thuộc
- Trong C++ không có quản lý phụ thuộc thống nhất, và đa số dùng trình quản lý gói của hệ thống. Tuy nhiên, đây không phải ý tưởng hay.
- Quan điểm của tác giả về quản lý phụ thuộc là dùng git submodule và biên dịch từ mã nguồn.
Ý kiến của GN⁺
- Bài viết này cung cấp một hướng dẫn từng bước hữu ích cho các kỹ sư phần mềm mới tiếp quản codebase C++.
- Việc xử lý code legacy là thách thức phổ biến với nhiều lập trình viên, và bài viết đưa ra lời khuyên thực tế cho tình huống đó.
- Việc nhấn mạnh tầm quan trọng của test trong quá trình cải thiện codebase phản ánh các thực hành phát triển phần mềm tốt.
- Quan điểm của tác giả về quản lý phụ thuộc có thể gây tranh cãi; trong các dự án thực tế, nhiều trường hợp vẫn dùng thành công các package manager hiện đại như Conan hoặc vcpkg.
- Khi đưa công nghệ vào sử dụng, cần cân nhắc đặc thù của dự án và trình độ kỹ thuật của nhóm; bài viết này có thể là điểm khởi đầu tốt để đưa ra các quyết định đó.
1 bình luận
Ý kiến trên Hacker News
Một số bình luận trên Hacker News đưa ra lời khuyên khi tiếp quản một dự án C++:
-Wall: sửa các cảnh báo để khắc phục vấn đề trong mã, và trong một số trường hợp hiếm hoi có thể bỏ qua cảnh báo sau khi đã hiểu rõ chúng.Các bình luận khác cho rằng điều quan trọng là phải đưa vào CI, linting, auto-formatting trước:
Có một người dùng đề xuất chuyển sang một nhóm hoặc công ty mới.
Cũng có những bình luận nhắc đến tầm quan trọng của công cụ và kỹ thuật để hiểu mã:
Một bình luận đưa ra lời khuyên về việc thêm CI, linters, fuzzing, auto-formatting để hiện đại hóa dự án:
Một bình luận khác chỉ trích lời khuyên viết lại một phần bằng ngôn ngữ an toàn bộ nhớ:
Cũng có bình luận cho rằng dùng git submodule và cách biên dịch từ mã nguồn tốt hơn package manager:
Những bình luận này đưa ra nhiều cách tiếp cận và lời khuyên khác nhau khi tiếp quản một dự án C++, đồng thời thể hiện nhiều quan điểm về quản lý dự án, hiểu mã, refactor và chiến lược hiện đại hóa.