Tôi muốn thêm một cái gì đó được gợi ý bởi các câu trả lời khác, nhưng tôi không nghĩ đã được đề cập rõ ràng:
@puck nói "Vẫn không có gì đảm bảo đối số được đề cập đầu tiên trong tên hàm thực sự là tham số đầu tiên."
@cbojar nói "Sử dụng các loại thay vì các đối số mơ hồ"
Vấn đề là ngôn ngữ lập trình không hiểu tên: chúng chỉ được coi là biểu tượng nguyên tử mờ đục. Do đó, giống như với các nhận xét mã, không nhất thiết có bất kỳ mối tương quan nào giữa chức năng được đặt tên và cách thức hoạt động của nó.
So sánh assertExpectedEqualsActual(foo, bar)
với một số lựa chọn thay thế (từ trang này và các nơi khác), như:
# Putting the arguments in a labelled structure
assertEquals({expected: foo, actual: bar})
# Using a keyword arguments language feature
assertEquals(expected=foo, actual=bar)
# Giving the arguments different types, forcing us to wrap them
assertEquals(Expected(foo), Actual(bar))
# Breaking the symmetry and attaching the code to one of the arguments
bar.Should().Be(foo)
Tất cả đều có cấu trúc nhiều hơn tên verbose, mang lại cho ngôn ngữ một cái gì đó không mờ đục để xem xét. Định nghĩa và cách sử dụng của hàm cũng phụ thuộc vào cấu trúc này, do đó, nó không thể không đồng bộ với những gì triển khai đang thực hiện (như tên hoặc bình luận có thể).
Khi tôi gặp phải hoặc thấy trước một vấn đề như thế này, trước khi tôi hét vào máy tính của mình trong sự thất vọng, trước tiên tôi dành một chút thời gian để hỏi liệu có công bằng không khi đổ lỗi cho máy. Nói cách khác, máy có được cung cấp đủ thông tin để phân biệt thứ tôi muốn với thứ tôi yêu cầu không?
Một cuộc gọi như assertEqual(expected, actual)
có ý nghĩa nhiều như assertEqual(actual, expected)
vậy, vì vậy chúng ta dễ dàng khiến chúng bị lẫn lộn và để máy cày trước và làm sai. Nếu chúng ta sử dụng assertExpectedEqualsActual
thay thế, nó có thể khiến chúng ta ít mắc lỗi hơn, nhưng nó không cung cấp thêm thông tin cho máy (nó không thể hiểu tiếng Anh và việc chọn tên sẽ không ảnh hưởng đến ngữ nghĩa).
Điều làm cho các cách tiếp cận "có cấu trúc" được ưa thích hơn, như đối số từ khóa, trường được gắn nhãn, loại khác biệt, v.v. là thông tin bổ sung cũng có thể đọc được bằng máy , vì vậy chúng ta có thể phát hiện ra cách sử dụng máy không chính xác và giúp chúng ta làm đúng. Các assertEqual
trường hợp không phải là quá xấu, vì vấn đề duy nhất là thông điệp không chính xác. Một ví dụ độc ác hơn có thể là String replace(String old, String new, String content)
, dễ nhầm lẫn với String replace(String content, String old, String new)
nó có một ý nghĩa rất khác nhau. Một biện pháp khắc phục đơn giản là lấy một cặp [old, new]
, điều này sẽ gây ra lỗi gây ra lỗi ngay lập tức (ngay cả khi không có loại).
Lưu ý rằng ngay cả với các loại, chúng tôi có thể thấy mình không 'nói với máy những gì chúng tôi muốn'. Ví dụ, mô hình chống được gọi là "lập trình gõ chuỗi" coi tất cả dữ liệu là chuỗi, giúp dễ dàng có được các đối số lẫn lộn (như trường hợp này), để quên thực hiện một số bước (ví dụ: thoát), để vô tình phá vỡ bất biến (ví dụ: làm cho JSON không thể nhìn thấy), v.v.
Điều này cũng liên quan đến "mù boolean", trong đó chúng tôi tính toán một loạt các booleans (hoặc số, v.v.) trong một phần của mã, nhưng khi cố gắng sử dụng chúng trong một phần khác, chúng không rõ chúng thực sự đại diện cho cái gì chúng tôi đã có họ trộn lên, vv Hãy so sánh này để ví dụ như sự đếm riêng biệt có tên mô tả (ví dụ LOGGING_DISABLED
chứ không phải false
) và gây một thông báo lỗi nếu chúng tôi nhận được chúng lẫn lộn.