Prototype

はい。今日はPrototypeパターンです。Prototypeってのは「原型」という意味です。
http://svn.takatoshi.dyndns.org/public/pattern/trunk/prototype/
なにかすごーい複雑なオブジェクトがあって、それと全く同じものを作りたいという場合に使ったりするようです。複雑だから、また1からnewして・・・とかはめんどくさいし、そもそもどうやって作ったのかわかんないとかそういうときに使うと。はっきり言って最初はよくわからなかったけど、考えているうちにイメージできてきました。
例1)現実世界の話

目の前に一枚のA4用紙がある。何やら複雑なフォーマットの申し込み用紙のようだ。上司がこう言う。
「こんなのが引き出しの奥からでてきてな、すまんがこれと同じものを作ってくれないか?電子ファイルはないから。とりあえず100部な。よろしく。」
さて、こんなとき、席についてWordやExcelを立ち上げるだろうか?一番早いのはコピーしてしまうことだ。コピー機で。

例2)ソフトウェアの話

お絵描きソフトウェアがある。ユーザーは線を引いたり円を書いたり塗りつぶしたりできる。
さて、ユーザーが30分くらいかけて複雑な絵を完成させました。で、それと同じものをもう1つ作りたい様子。
で、どうやって複製するか?
プログラム的見地から言うと、どうやってそんなオブジェクトを作ったのかわからないよ!というわけ。
でもご安心を。オブジェクトは全部クラスで表現されています。じゃあ丸ごとコピーしちゃえばいいのだ。
メモリを確保して、、コピーする。
それだけ。

これがPrototypeパターン。なにかをもとにして新しいオブジェクトを作る。使う側はオブジェクトの作り方を知らないけど、とにかくこれと同じものを作ってね、と言えば作ってくれるというパターン。Factory Methodとかと同様、クラス生成に関するパターンということになる。Factory Methodってのはクラス生成に関するひな形(テンプレート)を持っていてクライアントは作り方の詳細を知らなくていいというやつですね。一方のPrototypeはだれもクラスの作り方を知らないからコピーしちゃおうということです。たぶん。

    • -

で、「コピー」というのが結構問題になりそうです。つまり、どこまでコピーするか?ということ。たとえばJavajava.lang.Object.cloneメソッドは一階層のみのコピーを行うようです。クラスをコピーする場合は、そのフィールドを単純にコピーするだけで、それが「どういうフィールドか?」ってのは考慮しない。あるフィールドが配列への参照だったとしても配列の中身をコピーするのではなくて配列への参照をコピーするだけだと。
こういうのをシャローコピー(shallow copy)というらしいです。浅いコピー。その反対はディープコピー(deep copy)です(たぶん)。深いコピー。コピーの仕方を変えたかったらサブクラスでオーバーライドしないといけませんね。

    • -

PrototypeといえばJavaScriptなわけですが、JavaScriptの場合はすべてのオブジェクトにprototypeというプロパティがあります。そしてprototypeもまたオブジェクトです。すべてのオブジェクトはこのprototypeを継承するので、そのプロパティを使ったり、新しいプロパティを設定したりできます。でもあまり詳しくは知らない。

    • -

http://www.tml.tkk.fi/~pnr/GoF-models/html/Prototype.html

Prototype Design Pattern(PPT)
上のやつのGoogleキャッシュ(HTML)
- Java プログラマのためのデザインパターン入門