"When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck." Duck types are public interfaces that are not tied to any specific class. They are about the object's methods and properties, rather that its inheritance from a certain class. In a nutshell:
Behaviour over class membership
Following that pattern helps to improve:
- readability (less code for all message sender)
- add enormous flexibility
- reduces class coupling and therefore increases maintainability
class Drug attr_accessor :dope, :brand end class Food attr_accessor :ingredients def labeling ingredients.map { |ingredient| ingredient.name }.join(', ') end end class Clothing attr_accessor :name endand a Bill class for printing out:
class Bill def print_name product return puts "#{product.brand} (#{product.dope})" if product.respond_to? :dope return puts product.labeling if product.respond_to? :labeling puts product.name end endThe Bill#print_name can be refactored by also duck typing the 3 classes:
class Drug attr_accessor :dope, :brand def name "#{product.brand} (#{product.dope})" end end class Food attr_accessor :ingredients def labeling ingredients.map { |ingredient| ingredient.name }.join(', ') end alias_method :name, :labeling end class Clothing attr_accessor :name endAll 3 classes now respond to name and can called in Bill#print_name like:
class Bill def print_name product puts product.name end endFurther articles of interest:
Supported by Ruby 2.1.1
Keine Kommentare:
Kommentar veröffentlichen