blog.fuktommy.com

小クラス主義

Javaでファイルに書き込もうとしたら、

new PrintWriter(new BufferedWriter(new FileWriter(filename)));

みたいなことしたりして、面倒くさい。 言語とかライブラリの思想によっては

new FileWriter(fileName, true);

みたいな感じで、バッファリングの有無をtrue/falseで切り替えるというアイデアもあるはずだし、 現にPython2.xでは

open(filename, 'w', bufsize)

みたくバッファサイズを指定できるようになってる (bufsizeは0と1が特別)。 じゃあJava(の標準ライブラリ)は面倒なだけかというと、 そんなことはなくて、 例えば僕がなんか Writer を作ったとしたら、 それに print() やバッファリング機能をつけることなく、

new PrintWriter(new BufferedWriter(new HogeWriter()));

でそれらの機能が使えるので便利。 確かにいちいち new... new... new... と書くのは面倒なので、 そこは適当なクラスを作って、

public PrintWrite openWritableFile(fileName) {
    return new PrintWriter(new BufferedWriter(new FileWriter(filename)));
}

というファクトリメソッドを準備しておけば、 以降は openWritableFile() を呼べばいいので手間はない。

さて、問題は自分で何かライブラリを作るときのことで、 例えば何かの入出力を扱う機能を作ったとします。 hoge.read() したり hoge.write() したりして使う。 ところがあとから読込み専用モードを作りたくなったとして、 上のPythonの例(大クラス主義)のように

new FileHoge(filename, false)

とwritableフラグにfalseを指定するのか、Javaの例(小クラス主義)のように

new ReadonlyHoge(new FileHoge(filename))

という別のクラスを作るのかというのが考え所で、 writableフラグ方式は素直な気がするけど、 FileHogeの他にSocketHogeなんてもの作ったら SocketHogeにもwritableフラグの処理を書くのかと思うと、 ReadonlyHogeの方がいいんじゃないの、という気もします。 FileHoge, SocketHoge, ReadonlyHogeは全部Hogeインタフェースを実装している、 みたいな雰囲気で読んでね。

あ、Javaが小クラス主義なのは異論少ないと思うけど、 Pythonの標準ライブラリは小クラス主義で、 Rubyは大クラス主義だと、Rubyに詳しい人が言ってたので、 そうなんじゃないかなあ。 Pythonはあまりクラスは意識しないので、 例えばopen()が内部では

def open(filename, mode='r', bufsize=0):
    if bufsize == 0:
        return File(filename, mode)
    elif bufsize == 1:
        return LineBufferedFile(File(filename, mode))
    else:
        return BufferedFile(File(filename, mode), bufsize)

みたくなっていたとしても、たぶん僕は気付かない。

話をもどして、writableフラグかReadonlyHogeか。 読み込み専用が後付けの機能で FileHogeに手を入れるのが面倒だと思ったらReadonlyHogeかなあ。 SocketHogeがあるとか、作るかもなあ、という流れでもReadonlyHogeでしょう。 逆に読み込み専用というのはFileHogeにしかない機能なんだ ということならwritableフラグかなあ。 結局は今後どう拡張されるかの「読み」にかかってくるわけか。

Copyright© 1998-2014 Fuktommy. All Rights Reserved.
webmaster@fuktommy.com (Legal Notices)