Code tởm #3: If else hỗn độn
Bài đăng này đã không được cập nhật trong 6 năm
Triết học là một thứ hack não bạn đọc, và đôi khi 1 đống điều kiện if else cũng có tác dụng tương tự...
# Code siêu bốc mùi
# sinh ra trong quá trình trưởng thành của lập trình viên
# và đa số thì người cho ra chả phải là người gánh chịu...
# Nào hãy hít một hơi thật sâu và ngắm đoạn code sau đây:
if weather.raining
if current_time > 7
if today.sunday?
if you.sleepy?
go_back_to_sleep
end
else
wake_up
if coffee.present?
drink_coffee
end
go_to_work
end
else
go_back_to_sleep
end
else
if current_time > 7
unless today.sunday?
go_to_work
end
else
do_exercise
end
end
Điều kiện. Là thứ dễ trở nên bốc mùi nhất.
Mỗi khi muốn mở rộng một method, thêm các trường hợp cho nó, suy nghĩ đầu tiên ập đến sẽ là: "thêm tí điều kiện, DONE!"
Điều này không khiến method thối ngay, nguyên do là qua tay nhiều người, mỗi người "thêm tí", lâu dài nó sẽ phình ra thành nhúm code với hàng tá nhánh if else.
Tuy nhiên, dù nhanh bẩn, nhưng nó cũng dễ dọn, chúng ta hãy cùng điểm qua một vài skill cơ bản dễ chơi dễ trúng thưởng sau.
Skill 1: truthy & falsy
Trong Ruby, ngoài nil và false ra, cái méo gì cũng đúng. Nên đôi khi, không nhất thiết phải xải #nil? hay #present?, #blank cho dài.
(Điều này sẽ khác so với kha khá các ngôn ngữ, dí dụ như ở Javascript, string rỗng, array rỗng hay số 0 cũng có giá trị là "false" :V)
# bad
if coffee.present?
drink_coffee
end
# good
drink_coffee if coffee
Skill 2: Group conditions
Nhóm điều kiện thay vì lồng nó vào nhau.
If mà không đi với else, hãy nhóm nó vào điều kiện bên ngoài.
# bad
if today.sunday?
if you.sleepy? # ko đi với else -> cho dung hợp với cái bên trên
go_back_to_sleep
end
...
# good
if today.sunday? && you.sleepy?
go_back_to_sleep
...
Skill 3: Guard conditions
Ngăn cản mọi trường hợp ngoại lệ ở ngay đầu method.
(cái xì tai này rất phổ biến với team xài NodeJs, với cái tên là "error first")
# not so bad but can still be better
if today.sunday? && you.sleepy?
go_back_to_sleep
else
wake_up
drink_coffee if coffee
go_to_work
end
# nice!
return go_back_to_sleep if today.sunday? && you.sleepy?
wake_up
drink_coffee if coffee
go_to_work
Một chút skill 1, cộng một tí skill 2 và kèm thêm xiu xíu skill 3, ta được thành quả sau:
# awesome!!
if weather.raining
return go_back_to_sleep if today.sunday? && you.sleepy? && current_time > 7
wake_up
drink_coffee if coffee
go_to_work
else
do_exercise if current_time < 7
go_to_work unless today.sunday?
end
Đôi lời kết
-
Mấy skill trên chả phải hữu hiệu cũng chả hề tối ưu nhất, bạn hoàn toàn có thể dùng nhiều cách hay ho hơn được biết với cái tên như "extract condition", "extract logic", ... hay là dùng "porlymorphic". Tuy nhiên, cái giá phải trả cho code sạch hơn sẽ là code bị thay đổi nhiều hơn. Và chắn chắn là team bạn sẽ chả thích điều này đâu ==!
-
Khi refactor các condition (thực ra refactor cái vẹo gì cũng vậy), hãy luôn luôn có unit test để chống lưng cho code của bạn nhé. Chả ai quan ngại bạn viết có chuẩn hay không cả. Shut up & show me the tests (họ nói vậy đấy :v)
-
"Úi xời lắm chuyện, thêm tí điều kiện, hơi bẩn chút thôi không sao hết" => Hãy nhớ đây mới là nguồn gốc của code bẩn bạn nhé =)))
Thank you for reading! Happy coding!
All rights reserved