Ban đầu, tôi đã học được rất nhiều ý tưởng này từ Confident Ruby, một trong những cuốn sách Ruby yêu thích của tôi. Nếu bạn thích bài đăng này, bạn nên mua nó và đọc toàn bộ. Có vậy nhiều thứ tốt trong đó.
current_user
của bạn phương thức trả về một User
, ngoại trừ khi không có người dùng và nó trả về nil. Một search
phương thức trả về một Array
trong số các kết quả, trừ khi chỉ có một kết quả và thay vào đó, nó chỉ trả về kết quả đó. Có vẻ hợp lý, phải không? Thậm chí có thể tiện lợi!
Nhưng chẳng bao lâu nữa, những quyết định này sẽ chôn vùi mã của bạn dưới hàng núi câu lệnh if. Có thể đó là một loạt các if kind_of?
rắc khắp nơi. Hoặc có thể bạn cảm thấy như bạn phải kiểm tra số không ở mọi nơi. Hoặc tệ hơn, NoMethodError
s bắt đầu hiển thị bất cứ khi nào bạn gửi một tính năng mới. Đoán đã đến lúc cho một hotfix khác!
Tuy nhiên, có một cách để ngăn chặn điều này và tất cả những gì cần làm là một chút cẩn thận.
Nguyên tắc mạnh mẽ
Có một nguyên tắc trong máy tính nói rằng,
Hãy thận trọng trong những gì bạn làm, tự do trong những gì bạn chấp nhận từ người khác.
Bạn có thể áp dụng nguyên tắc này cho các phương thức Ruby của mình. Các phương thức bạn viết phải chấp nhận đầu vào hợp lý và phải trả lại đầu ra nhất quán.
Tập trung vào phần cuối cùng:Khi ai đó gọi một phương thức bạn đã viết, họ sẽ biết chính xác phương thức đó sẽ trả về.
Hãy cẩn thận về kết quả đầu ra của bạn
Hãy xem cách triển khai ActiveRecord::Errors#on
của Rails 2.1 :
# File activerecord/lib/active_record/validations.rb, line 212
def on(attribute)
attribute = attribute.to_s
return nil unless @errors.has_key?(attribute)
errors = @errors[attribute].map(&:to_s)
errors.size == 1 ? errors.first : errors
end
Khi được gọi, nó có thể trả về một Array
của String
s, một String
hoặc nil
. Người gọi tùy thuộc vào việc tìm ra loại đối tượng mà họ đang xử lý. Đây là một ý tưởng tồi:
-
Người gọi phải tạo mã của chính mình với tính năng kiểm tra kiểu gây khó chịu.
-
Người gọi phải biết rất nhiều về phương thức nó đang gọi. Ở mức tối thiểu, nó cần biết mọi loại đối tượng mà phương thức có thể trả về và khi nào mỗi loại có thể được trả về.
-
Bạn có nhiều trường hợp cạnh để kiểm tra. Nếu bạn muốn tự tin rằng mã của bạn đang làm những gì nó phải làm, bạn phải thử cả ba tình huống.
Các phương pháp của bạn phải nhất quán về những gì chúng trả về. Nếu bạn thường trả về một Array
, hãy làm những gì bạn cần làm để luôn luôn trả về một Array
. Nếu bạn thường trả về một User
, nhưng đôi khi trả về nil, bạn có thể tạo đối tượng Null User và trả về that thay vì con số không.
Bạn thậm chí có thể bớt nghiêm khắc hơn:“Tôi sẽ trả lại một thứ bao gồm Taggable
mô-đun ”. Bạn có thể nói chung chung hơn:“Tôi sẽ trả lại thứ gì đó có id
và name
thuộc tính." Điều quan trọng là tính nhất quán và đảm bảo rằng người gọi của bạn biết điều gì sẽ xảy ra.
jQuery là một ví dụ thú vị. Hầu hết các phương thức jQuery trả về cùng một loại Array
-như đối tượng. Do đó, các phương thức của jQuery có thể kết hợp cực kỳ linh hoạt và bạn có thể thực hiện rất nhiều công việc chỉ trong một dòng mã.
Và trong trường hợp bạn đang thắc mắc, Rails đã sửa phương pháp đó trong các phiên bản sau:
# File activemodel/lib/active_model/errors.rb, line 133
def [](attribute)
get(attribute.to_sym) || set(attribute.to_sym, [])
end
Bây giờ nó luôn trả về một Array
. Đơn giản hơn cho họ và đơn giản hơn cho chúng tôi.
Loại bỏ sự không nhất quán
Lần tới khi bạn thấy mình trả về “Một Array
hoặc nil
”, Chỉ cần trả về một Array
. Hãy xem qua cơ sở mã của bạn và xem bạn đang sử dụng kind_of?
và respond_to?
. Xem liệu bạn có thể cấu trúc lại các phương thức được gọi bởi mã đó để trả về một loại duy nhất hay không.
Và hãy xem các giả định bạn có thể đưa ra về giá trị trả lại của mình xuất hiện trong dự án của bạn và đơn giản hóa tất cả các mã lân cận của bạn.