Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Ruby

Nâng cao độ tin cậy code Ruby với Nguyên tắc Robustness (Sự mạnh mẽ)

Tôi học nhiều ý tưởng này từ Confident Ruby, một trong những cuốn sách Ruby yêu thích. Nếu bạn thích bài này, hãy mua và đọc toàn bộ. Có rất nhiều thứ hay bên trong.

Method current_user của bạn trả về User, trừ khi không có user thì trả về nil. Method search trả về Array kết quả, trừ khi chỉ có một kết quả, nó trả về chính kết quả đó. Có vẻ hợp lý, đúng? Thậm chí còn tiện lợi!

Nhưng sớm muộn, những quyết định này sẽ chôn code của bạn dưới núi if statement. Có thể là một đống if kind_of? rải rác khắp nơi. Hoặc bạn cảm thấy phải check nil khắp nơi. Hoặc tệ hơn, NoMethodError bắt đầu xuất hiện mỗi khi bạn deploy tính năng mới. Đoán là lúc cho hotfix khác!

Có cách ngăn chặn điều này, và chỉ cần chút suy nghĩ.

Nguyên tắc Robustness (Sự mạnh mẽ)

Có một nguyên tắc trong computing nói rằng,

Hãy bảo thủ trong những gì bạn làm, hãy cởi mở 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 method Ruby. Method bạn viết nên chấp nhận input hợp lý, và nên trả về output nhất quán.

Tập trung vào phần sau: Khi ai đó gọi method bạn viết, họ nên biết chính xác method đó sẽ trả về gì.

Hãy suy nghĩ kỹ về output của bạn

Hãy xem implementation của ActiveRecord::Errors#on trong 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 gọi, nó có thể trả về Array của String, một String, hoặc nil. Việc caller phải xử lý loại object nào là trách nhiệm của caller. Đây là ý tưởng xấu:

  • Caller phải làm bẩn code của mình với type-checking rườm rà.

  • Caller phải biết rất nhiều về method nó đang gọi. Tối thiểu, nó cần biết mọi loại object method có thể trả về và khi nào mỗi loại được trả về.

  • Bạn có nhiều edge case để test hơn. Nếu bạn muốn tự tin code làm đúng việc, bạn phải thử cả ba kịch bản.

Method của bạn nên nhất quán về những gì chúng trả về. Nếu bạn thường trả về Array, hãy làm những gì cần để luôn luôn trả về Array. Nếu bạn thường trả về User, nhưng đôi khi trả về nil, bạn có thể tạo Null User object và trả về đó thay vì nil.

Bạn thậm chí có thể kém nghiêm ngặt hơn: "Tôi sẽ trả về thứ gì đó include module Taggable". Bạn có thể tổng quát hơn: "Tôi sẽ trả về thứ có attribute id và name." Điều quan trọng là nhất quán và đảm bảo caller biết đà mong đợi.

jQuery là ví dụ thú vị. Hầu hết method jQuery trả về cùng loại object giống Array. Vì thế, method jQuery cực kỳ composable, và bạn có thể làm lượng công việc điên rồ trong một dòng code.

Và nếu bạn tò mò, Rails đã sửa method đó 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ề Array. Đơn giản cho họ, và đơn giản cho chúng ta.

Diệt sự không nhất quán

Lần sau khi bạn thấy mình trả về "Một Array hoặc nil", chỉ cần trả về Array. Nhìn qua codebase và xem nơi bạn dùng kind_of? và respond_to?. Xem có thể refactor method được gọi bởi code đó để trả về kiểu đơn nhất không.

Và xem như những giả định bạn có thể làm về giá trị trả về lan tỏa qua project và đơn giản hóa tất cả code xung quanh.