Skip to content

Instantly share code, notes, and snippets.

@hyoshida
Last active August 29, 2015 14:17
Show Gist options
  • Save hyoshida/fb62eaf7fbcd7befda2f to your computer and use it in GitHub Desktop.
Save hyoshida/fb62eaf7fbcd7befda2f to your computer and use it in GitHub Desktop.
More readable interface in Ruby
# ----------------------------------------------------------------------
#
# I think Java style interface is unreadable in Ruby.
# Because must methods and normal methods are mixed.
#
# Ruby で Java の interface のような実装をすると、
# 普通のメソッドと実装必須なメソッドが混ざってわかりにくい。
#
class Car
def engine
raise NotImplementedError, 'Please implement `engine` method.'
end
def start
"#{engine.class.name} is started!"
end
end
class AwesomeEngine
end
class AwesomeCar < Car
def engine
@engine ||= AwesomeEngine.new
end
def awesome_feature
'hoge'
end
end
awesome_car = AwesomeCar.new
awesome_car.start
#=> "AwesomeEngine is started!"
class AwfulCar < Car
end
awful_car = AwfulCar.new
awful_car.start
#=> NotImplementedError: Please implement `engine` method.
# ----------------------------------------------------------------------
#
# I'd like to make a suggestion.
# Explicit the must method using the class method. It is more readable.
# (I don't know the name of this technique... Can anybody teach me?)
#
# そこで提案。
# クラスメソッドで必須な処理を明示化するとたぶんきっと分かりやすくなる。
# (この技の名前がわからないので誰か教えてください)
#
class Car
class << self
def engine(engine_class)
@engine_class = engine_class
end
end
def engine
return @engine if @engine
engine_class = self.class.instance_variable_get(:@engine_class)
raise NotImplementedError, 'Please call `engine` method.' unless engine_class
@engine = engine_class.new
end
def start
"#{engine.class.name} is started!"
end
end
class AwesomeEngine
end
class AwesomeCar < Car
engine AwesomeEngine
def awesome_feature
'hoge'
end
end
awesome_car = AwesomeCar.new
awesome_car.start
#=> "AwesomeEngine is started!"
class AwfulCar < Car
end
awful_car = AwfulCar.new
awful_car.start
#=> NotImplementedError: Please call `engine` method.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment