オブジェクト指向プログラミングは、オブジェクトが連携して動くとかオブジェクトがメッセージを送りあって動くとか言われるが、オブジェクト指向プログラミングはどういうものかを説明するときは、その準備をするところも含めて語らないといけない気がする。
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