2008/09/18(木)にゅーふれーむわーくの悩み4
例によって、staticなの? instanceなの? 問題と格闘中。
いい加減こればっか悩んでても先に進まないので、割り切ってとりあえず作ってみて使ってみてそれからまた考えるかもしれないということにした。
オブジェクト指向として「美しい」というか「あるべき姿」っていうのは、ライブラリ実装者の立場としてはやはりnewして使われるクラスとして実装されているのが自然だと思う。このとき、Texture.Load()をstaticメソッドとして実装するのは間違いで、newされたDeviceのinstanceのメソッドとしてLoadTextureなどというメソッドを実装するのが綺麗だと思う。個々のTextureインスタンスはDeviceに依存するのだから、TextureのLoadメソッドは、Deviceと同水準におかないといけないはずだ。
どうしても、Texture.Loadというstaticメソッドを使いたいとしたら……。
すべてはそこにあるもの という発想はできないだろうかと考えてみる。というのは、たとえばファイルシステムに対するIOなんかを考えてみたとき。System.IO名前空間には、File.OpenRead()なんてメソッドがあったりするけど、ご存じの通り、こいつらは指定したファイルを開いてStreamを返してくる。この「File」クラス、というか「ファイルシステム」っていうのは、プログラムがインスタンス化される前からそこにあったもので、それはシステムにおいて唯一なものである。
「すべてはそこにあるもの」っていうのは、つまり、Direct3DのDeviceも「最初からそこにあったこと」にしてしまえば、あるいは全部 staticで実装するのもまぁわからんくはないかなぁという発想。
私の自分のライブラリ(というよりもコードテンプレートかも……)は「何も書かなくてもDirect3Dのウィンドウができて、DirectSoundやDirectInputなんかの初期化処理も全部勝手に終わってくれる」設計になってるので(今のところは)、アプリケーション実装者(=ライブラリ使用者≠ライブラリ実装者)から見た場合は、実際にコードを書き始める時点でデバイスは1つ用意されている。それを唯一なものと見なせば、全部staticメソッドっていうのもわからなくはないかなぁという気がしてきた。ただ、そこには、ライブラリ実装者がついた嘘があるから、他の用途に使い回しにくくなるけど。
DirectSoundもDirectInputもそれぞれinstanceなのだけど、これらのメソッドだってもうほとんどstatic的に呼んでいるわけで(LoadSoundだの、Key.IsPushedだの...)、これらを全部「そこにあったもの」として、static化してしまおうかなぁと思う。普通に考えて、SoundやInputは2つ作る機会はないはずだし、こいつらはstatic化することにあまり抵抗はないのに、どうしてかなぁ……。音を同時にいっぱい鳴らすにはDirectSound.Deviceは1個でいいけど、ウィンドウをいっぱい開くにはDirect3D.Deviceがたくさん必要なせいかしら。うーん。全部staticにすることにしようか。な。
まだ、影も形もできてない、というと言い過ぎかも知れないけれど、実際影くらいしかできてないから、明日のサークルでライブラリを発表しようと思ってたけど……もし、間に合わなかったらもうライブラリ作りなんてやめてしまえ!