Code
refactoring là hoạt động chỉnh sửa khiến source code dễ đọc hơn, được tổ chức
khoa học hơn, và (có thể) có kiến trúc / cấu trúc tốt hơn nhưng không làm thay
đổi hành vi của hệ thống về mặt chức năng.
Việc
này giống như chúng ta sắp đặt lại hệ thống điện trong nhà theo một cách khoa học
hơn nhưng vẫn đảm giữ nguyên vị trí và chức năng của những công tắc, ổ cắm trên
tường.
Thực
hiện code refactoring như thế nào?
Những
cách thức đơn giản nhất bạn có thể tham khảo tại http://refactoring.com của
huyền thoại Martin Fowler. Tại đây bạn có thể tham khảo những kỹ thuật đơn giản
nhất và dấu hiệu nhận biết một đoạn code có thể được refactor; từ chuyện đơn giản
nhất như chuyển 2 đoạn code giống nhau thành một hàm đến sự liên kết giữa các đối
tượng nhằm đảm bảo tính hướng đối tượng của chương trình.
Một
chú ý hay là, đôi khi bạn thấy hướng dẫn refactor một đoạn code từ A sang B và
nơi khác lại hướng dẫn refactor đoạn code từ B sang A. Điều này không mâu thuẫn,
bởi “A hay B tốt hơn?” thì chỉ chính bạn mới có câu trả lời xác đáng trong ngữ
cảnh của source code hiện tại. Tuy vậy, vẫn sẽ có những chuẩn chung để một đoạn
code được coi là “tốt” hay “dở”; ví dụ, đặt tên biến là a là điều không chấp nhận
được trong phát triển phần mềm.
Và
hãy nhớ rằng, code refactoring không làm thay đổi hành vi của chức năng hay hệ
thống; do đó, kết quả của việc kiểm thử phải không đổi.
Khi
nào thực hiện code refactoring?
Về
lý thuyết, hãy thực hiện code refactoring bất cứ khi nào có thể.
Trước
khi commit, mỗi lập trình viên cần đọc lại những đoạn code mình đã viết và xem
có thể cải tiến được không.
Sau
một thời gian, nhóm phát triển cần cùng nhau nhìn lại xem có thể cải tiến ở những
điểm nào và cùng thực hiện code refactoring. Tuy nhiên, vấn đề không đơn giản
như vậy.
Điều
gì ngăn cản code refactoring?
Một
số lý do được chia sẻ như sau:
- Trình
độ kém. Khi nhóm phát triển không có hiểu biết sâu sắc về OOP thì đương
nhiên những đoạn code ban đầu viết ra sẽ rất “dở”, nhưng quan trọng là họ hoàn
toàn không biết rằng nó “dở”. Việc này càng nguy hại nếu không thực hiện code
refactoring bởi nhóm sẽ mãi duy trì năng lực hiện có.
- Chấp
nhận. Sau một thời gian dài, nhóm phát triển nhận ra có rất nhiều đoạn
code “dở” nhưng nhóm vẫn chấp nhận bởi số lượng code “dở” là quá nhiều và có tư
tưởng chấp nhận “sống chung với lũ”, hoặc nghĩ tới việc viết lại toàn bộ hệ thống.
- Không
có thời gian. Đây là lý do khá xác đáng; bởi như tôi nói ở trên,
khách hàng hoàn toàn không nhận được lợi ích trực tiếp từ code refactoring, nên
khó thuyết phục họ trả tiền cho nhóm phát triển thực hiện code refactoring.
- Tuy
vậy, những lý do này sẽ đẩy cả nhóm phát triển vào một vòng luẩn quẩn không hồi
kết: trình độ kém và sức ép thời gian đưa ra những đoạn code “dở”, không thực
hiện code refactoring khiến trình độ không được cải thiện, sau một thời gian
đành chấp nhận, khiến sức ép thời gian càng lớn, không thể thực hiện code
refactoring, và trình độ không được cải thiện… Và dự án, từ đam mê bỗng thành
gánh nặng với nhóm phát triển, khiến động lực làm việc không còn đúng.
Vậy
giải pháp là gì?
Từ
góc độ một lập trình viên, tôi cho rằng việc không thực hiện code refactoring
là trách nhiệm của lập trình viên; do họ không đủ đam mê và trách nhiệm cần thiết
với “đứa con tinh thần” của mình; không khác một nhà văn viết ra những tác phẩm
rẻ tiền. Tuy vậy, người “lãnh đạo” trong dự án Agile cũng phải có trách nhiệm tạo
ra những “khoảng lặng” về những chức năng cần bổ sung để nhóm phát triển thực
hiện code refactoring. Việc này diễn ra càng đều đặn, trình độ và năng suất của
lập trình viên càng cao bởi code refactoring chính là một cách nâng cao tay nghề
và hiểu biết sâu sắc dựa trên những best practice cải tiến họ tốt hơn. 1 ngày
dành cho code refactoring hôm nay có thể giảm bớt 10 ngày phát triển buồn tẻ
sau này.
Giải
pháp cho source code đã quá “cũ”?
Khi
chúng ta “động đâu cũng thấy vấn đề” trong source code, chấp nhận hoặc làm lại
từ đầu thường là giải pháp; tuy vậy, cả 2 giải pháp này đều rất tốn kém. Code
refactoring có thể là một giải pháp:
- Sử dụng công cụ phân tích source code để tìm ra những
đoạn code “dở”
- Nhóm phát triển cùng quét nhanh qua mã nguồn để đánh
giá và tìm thêm những vấn đề
- Ước lượng tổng thời gian cần cho code refactoring
- Định nghĩa và lên kế hoạch việc kiểm thử. Việc này rất
quan trọng vì code refactoring phải đảm bảo không thay đổi hành vi của chức
năng và hệ thống. Lúc này automation test được ưu tiên bởi khối lượng kiểm thử
nhiều. Không nên (thậm chí là nghiêm cấm) thực hiện code refactoring nếu không
có kế hoạch kiểm thử tốt.
- Lên kế hoạch và thực hiện dần, từng phần. Thật tuyệt vời
nếu chúng ta có toàn bộ thời gian để thực hiện; nếu không, hãy thực hiện từng
phần song song với quá trình phát triển tiếp. Và hãy kiên nhẫn, chúng ta không
thể thấy kết quả chỉ sau 1 vài ngày.
Thât
ra, code refactoring là công việc rất đơn giản, đến mức người ta dễ dàng bỏ qua
code refactoring để nghĩ tới architect refactoring hay structure refactoring. Tuy
nhiên, khi thực hiện code refactoring tốt, những design pattern sẽ dần được
hình thành và từ đó kiến trúc mới cũng sẽ được hình thành.
Tác giả: Nguyễn Hiển
Đăng nhận xét