Last active
August 29, 2015 14:17
-
-
Save hyoshida/fb62eaf7fbcd7befda2f to your computer and use it in GitHub Desktop.
More readable interface in Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ---------------------------------------------------------------------- | |
# | |
# 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