Code smell
Nội dung bài · 5 mục
- 1.Khái niệm
- 2.Ví dụ
- 3.Thử ngay
- 4.Lỗi hay gặp
- 5.Tóm tắt
Code chạy đúng chưa chắc đã dễ sửa. Có những dấu hiệu báo trước lần sửa sau sẽ vất vả: cùng một con số chép ở ba nơi, method dài hai trăm dòng. Nhận ra chúng sớm thì sửa rẻ hơn nhiều so với lúc chúng đã gây lỗi.
Khái niệm
👃 Code smell: dấu hiệu trong code cho thấy code khó hiểu, khó sửa, dù chưa chắc đã là lỗi.
| Smell | Dấu hiệu | Cách sửa thường dùng |
|---|---|---|
| Trùng lặp | cùng một công thức chép ở nhiều nơi | tách thành một method |
| Method dài | phải cuộn mới đọc hết một method | tách thành nhiều method nhỏ có tên |
| Số trần (magic number) | 110, 500000 nằm giữa code, không có tên |
đặt thành hằng có tên |
| Danh sách tham số dài | method nhận năm, sáu tham số | gom thành một class |
Ví dụ
Tổng tiền có VAT 10% được tính ở hai nơi:
// Main.java
void main() {
System.out.println(cartTotal(100000));
System.out.println(invoiceTotal(100000));
}
long cartTotal(long subtotal) {
return subtotal * 110 / 100;
}
long invoiceTotal(long subtotal) {
return subtotal * 110 / 100;
}Có hai smell cùng lúc: 110 là số trần, không cho biết nó là gì, và công
thức bị trùng ở hai method. Sửa bằng một hằng và một method dùng chung:
// Main.java
static final int VAT_PERCENT = 10;
void main() {
System.out.println(cartTotal(100000));
System.out.println(invoiceTotal(100000));
}
long withVat(long subtotal) {
return subtotal * (100 + VAT_PERCENT) / 100;
}
long cartTotal(long subtotal) {
return withVat(subtotal);
}
long invoiceTotal(long subtotal) {
return withVat(subtotal);
}static finalkhai báo hằng số: gán một lần khi viết code, không đổi được lúc chạy. Tên hằng viếtUPPER_SNAKE_CASE.- Tên
VAT_PERCENTnói rõ con số là gì. VAT đổi thì sửa đúng một dòng. - Hai method gọi chung
withVat, công thức chỉ còn một chỗ.
Thử ngay
Nhà nước giảm VAT còn 8%. Với bản chưa sửa, lập trình viên chỉ nhớ đổi
cartTotal thành subtotal * 108 / 100, quên invoiceTotal. Chạy lại.
Đoán trước khi chạy: số tiền ở giỏ hàng và trên hoá đơn có khớp nhau không?
Xem kết quả
108000
110000Không khớp: khách thấy 108.000 trong giỏ nhưng hoá đơn ghi 110.000. Công thức
bị chép ở hai nơi thì sớm muộn sẽ có lúc sửa sót một nơi. Với bản đã sửa, chỉ
cần đổi VAT_PERCENT là cả hai cùng đúng.
Lỗi hay gặp
Đặt hằng mà tên không nói gì. Tên như X vẫn không cho biết con số là
gì, số trần chỉ đổi chỗ đứng.
// SAI — X là gì?
// Main.java
static final int X = 10;
void main() {
System.out.println(100000 * X / 100);
}// ĐÚNG — tên nói rõ ý nghĩa
// Main.java
static final int VAT_PERCENT = 10;
void main() {
System.out.println(100000 * VAT_PERCENT / 100);
}Tóm tắt
- Code smell là dấu hiệu code khó sửa, chưa chắc là lỗi.
- Bốn smell hay gặp: trùng lặp, method dài, số trần, tham số dài.
- Số trần thay bằng hằng
static finalcó tên. Công thức trùng gom về một method. - Tên hằng phải nói rõ con số là gì.
Tự kiểm tra
0/3 câuif (total > 500000) xuất hiện ở năm file khác nhau. Smell nào, sửa thế nào?
Method createOrder(name, phone, email, street, city, district) có smell gì?
Khai báo static final int VAT_PERCENT = 10;. Có đổi được VAT_PERCENT lúc chương trình đang chạy không?