- are not readable
- duplicate code or responsibility inside and outside the method
class Food def self.order vegetarian=false return "Vegetarian food" if vegetarian "Conventional food" end endThe original code works so far, but using it is no laughing matter:
Food.order true # => "Vegetarian food" Food.order # => "Conventional food"What does "Food.order true" express? Does it mean "The Food order is no lie and is meant seriously"? TrueClass and FalseClass are not expressive in no way.
Even following the expressive boolean pattern (Express boolean parameters the Ruby way!) is not the best choice:
Food.order :vegetarian # => "Vegetarian food" Food.order # => "Conventional food"That is a little nicer, but it would be great to make even this work:
Food.order :conventional # => "Conventional food"Every time the API is yours you have the choice to make it work great.
Use Enums instead of Booleans!
The original class should be refactored and expect Enum like:
class Food def self.order type=:conventional types = %i(conventional vegetarian) fail "Invalid Food type." unless types.member? type return "Conventional food" if type.eql? :conventional "Vegetarian food" end endand then:
Food.order :vegetarian # => "Vegetarian food" Food.order :conventional # => "Conventional food" Food.order :something_else # => RuntimeError: # Invalid Food type. # Must one be of :conventional or :vegetarian.The Enum method definition directs to a strict parameter expectation, which prevents API misinterpretations.
Although it still couples code or responsibility from outside and inside the method, there is another pro for Enums. It is way more extensible than boolean parameters can be.
A new requirement wants vegan food to be added:
class Food def self.order type=:conventional types = %i(conventional vegetarian vegan) fail "Invalid Food type." unless types.member? type case type when :vegetarian "Vegetarian food" when :vegan "Vegan food" else "Conventional food" end end endForgive the usage of a case statement for simplicity reasons.
Every time a new type of food has to be added the method can be changed without hurting the message senders, whereas boolean parameters will ruin the public API.
Further articles of interest:
Supported by Ruby 2.1.1
Keine Kommentare:
Kommentar veröffentlichen