多態性が必要か否か

FizzBuzzをRubyで解くとする。このとき、いきなり:

100.fizzbuzz

のように、Fixnumのインスタンスメソッドとして実装しようとは思わない。

FizzBuzz.fizzbuzz(100)

のように、FizzBuzzモジュールのモジュール関数として実装するだろう。

しかし、fizzbuzzメソッドの引数としてRangeオブジェクトも渡せるようにしたくなったらどうか。

FizzBuzz.fizzbuzz(100)
FizzBuzz.fizzbuzz(10..100)

の代わりに:

100.fizzbuzz
(10..100).fizzbuzz

としたくなるかもしれない。

この場合、多態性が必要か否かが、モジュール関数にするかインスタンスメソッドにするかの判断基準となる。fizzbuzzは微妙かもしれないが、to_sのようにメソッドが汎用的であればあるほど、インスタンスメソッドへの欲求が強くなる。

インスタンス変数が複数回使われるか否か

Rangeへの対応は不要だが、FizzBuzz出力の区切り文字を指定させたくなったらどうか。

FizzBuzz.fizzbuzz(100, ",")
FizzBuzz.fizzbuzz(100, "\n")

とすべきか:

fizzbuzzer = FizzBuzzer.new
fizzbuzzer.delimiter = ","
fizzbuzzer.fizzbuzz(100)

とすべきか。

もし:

fizzbuzzer = FizzBuzzer.new
fizzbuzzer.delimiter = ","
fizzbuzzer.fizzbuzz(100)
fizzbuzzer.fizzbuzz(200)

のように、@delimiterが複数回使われるのであれば、インスタンスメソッドにするかもしれない。インスタンス変数の使われる回数が多いと予想されればされるほど、インスタンスメソッドへの欲求が強くなる。


なお:

FizzBuzz.fizzbuzz(100, ",")

のようにすると、それぞれの引数の意味が分かりにくくなると『クラス設計の考え方』で指摘されている。

ただ、キーワード引数を使えば、さほど問題にはならないだろう。

FizzBuzz.fizzbuzz(100, delimiter: ",", sleep: 1)