Chúng ta bắt đầu với ví dụ:
|
|
Bước 1 tạo unit test
Để có thể refactor hiệu quả chúng ta sẽ viết UT cho source này.
|
|
Refactoring
Step 1 : Phân tích và viết lại code dễ hiểu hơn
Đọc qua có thể thấy thuật toán ở đây như sau:
Giá trị valid là từ 0 -> 80. Nếu lớn hơn 40h sẽ được tính overtime. Chế độ overtime được quyết định bởi dạng hợp đồng. Nếu nhân viên làm việc theo giờ sẽ được tính với giá 1.5 còn bình thường vẫn 1. Hay nói cách khác, việc tính với rate khác chỉ có tác dụng với lao động theo giờ còn các chế độ khác không có gì khác biệt so với thông thường.
Chúng ta có thể viết lại code theo cách dưới đây:
- Biến đổi logic theo thuật toán phía trên
- Tách các biến hardcode cho dễ hiểu hơn
- Chạy lại testcase để đảm bảo UT vẫn chạy đúng
|
|
Nếu bạn nào không thích sử dụng thêm thư viện Math để tính overTimeHours thì có thể sử dụng toán tử một ngôi
|
|
Step 2 : Bỏ tham số boolean
Hãy luôn nhớ rằng, tham số flag dạng boolean luôn là một cách code tồi, vì nó là dấu hiệu của sự vi phạm quy tắc “single responsibility”. Bởi vì trong đoạn code sau đó sẽ thường đi kèm if(A) do B else do C nghĩa là nó sẽ làm 2 việc.
Đầu tiên việc dễ dàng nhất để có thể bỏ được biến boolean trong trường hợp này là chuyển nó thành biến của hàm như sau.
|
|
Điều này dẫn đến cần phải thay đổi source UT như sau:
|
|
Step 3 : Polymorphism
Nhìn vào UT chúng ta đang tạo ra 2 biến test của cùng một hàm với 2 flag true false. Điều này gợi ý chúng ta có thể sử dụng tính đa hình ở đây để tiếp tục refactor source như sau:
|
|
|
|
class test sẽ trở thành:
|
|
Từ đây chúng ta có thể chuyển hàm tính toán vào các class con và class PayCalculator trở thành class abstract và source chúng ta trở thành:
|
|
|
|
|
|
Design Pattern?
Nếu bạn muốn một bước xa hơn nữa, với những ví dụ phức tạp hơn ở đây chúng ta có thể sử dụng template method để tránh việc phải gọi lại validateHours ở các class con như sau:
|
|
|
|
|
|
Final class diagram:

Final source here
Refactoring is not only the art but also the money!