オブジェクト指向プログラミングは、オブジェクトが連携して動くとかオブジェクトがメッセージを送りあって動くとか言われるが、オブジェクト指向プログラミングはどういうものかを説明するときは、その準備をするところも含めて語らないといけない気がする。
1. 適切な粒度の部品ごとにオブジェクトを定義する。
2. 複合オブジェクトの組み立て(オブジェクトと通信先のオブジェクトの関連性を登録する)。
3. 代表であるオブジェクトのメソッドを呼び出す(オブジェクトに操作メッセージを送る)。
というのが正しい説明じゃないだろうか。
そういう考えでCoffeeScriptでFizzBuzzを作ってみた。
main = ->
out = new Outputer
fb = new FbGame(new Counter, out)
fb.addRule new FbRuleHitToSay("FizzBuzz", (n) -> n % 3 == 0 && n % 5 == 0)
fb.addRule new FbRuleHitToSay("Fizz" , (n) -> n % 3 == 0)
fb.addRule new FbRuleHitToSay("Buzz" , (n) -> n % 5 == 0)
fb.addRule new FbRuleNum()
fb.run()
out.flush()
class FbGame
constructor: (@cnt, @out) ->
@rules=[]
addRule: (rule) ->
@rules.push rule
run: ->
for n in @cnt.getList()
@out.print @conv(n)
conv: (n) ->
for rule in @rules
return rule.getStr(n) if rule.isHit(n)
class Counter
getList: -> [1..100]
class Outputer
constructor: ->
@out = []
print: (s) -> @out.push s
flush: -> console.log @out.join(",")
class FbRuleBase
constructor: ->
isHit: (n) ->
getStr: (n) ->
class FbRuleHitToSay extends FbRuleBase
constructor: (@sayStr, @isHitFunc) ->
isHit: (n) -> @isHitFunc n
getStr: (n) -> @sayStr
class FbRuleNum extends FbRuleBase
isHit: (n) -> true
getStr: (n) -> n