読書会(Java言語で学ぶデザインパターン入門)第2回議事録
[ 戻る ]
「Java言語で学ぶデザインパターン入門」を読む会 第2回議事録
日時:2001/12/15 10:00 - 17:30
場所:タイムインターメディア 会議室
参加者(敬称略、席の並び順):
西海、高橋(徹)、天野、小川、百瀬、武井、畠中、秋元、
福嶋、金井、中村、倉村、立見、岸田、高橋(智)
議事録: 秋元
今回は、Singleton, Prototype, Builder, Abstract Factory, Bridgeの
5つのパターンについて読み進めました。
■Singleton (p.58)
p.58
「システムで1つ」でいうシステムとは?
→PC1台という単位ではないね
→EXEとかプロセスとか?
→JavaでのSingletonの仕組みとして、VMに1個では?
→いやいや、クラスローダ毎になってしまうのでは
EJBではstaticフィールドを使っても、複数クラスローダが絡んでくる
ので、EJB全体をシステムとして「1つ」を保証するときは、DBなどを
使うのではないか
p.62
唯一のインスタンスの生成タイミング
→C++のイメージだと、staticなsingletonフィールドが初期化されないの
は違和感ある。これまで勘違いしていた。
→言語仕様にあるからには、最初に呼ばれる前にnew Singleton()される
ような実装は仕様に沿ってないことになる(実際にあるかどうかは別として)
→main()の中で、Singleton.getInstance()が呼ばれているところまで、
Singletonクラス自身がロードされないので、本文のような順序の出力
になる
問題5-1
→このクラスでやりたい事であれば、フィールドもメソッドもstaticに
してしまえば? インスタンスが1つに保証されはしないが、ここでやり
たいことは簡単にできそう
→じゃあSingletonを使いたい場合や理由は何? 違いはどこ?
→継承可能であること
→privateコンストラクタでは継承できないのでは?
→protectedコンストラクタを用意するのかなあ
protectedだとパッケージ内から見えてしまうけど
→他のInterfaceを実装したいとき
→他のクラスを継承したものをSingletonにしたいとき
→全部staticで十分な場合もあるが、オーバーライドなど、インスタ
ンスでなければ使えない機能を使う場合には、やはり本文にあるよ
うなSingletonを使う必要がある
問題5-3
→static フィールドを"= null"で初期化しているけど、何も書かなくても
nullになりますよね?
→わかりやすさから、書く作法にしているのでは?
→性能が落ちたりしないでしょうか?
→たぶんOKと思いますが、javapで二つを比較してもらえますか?
→ すでに別メールで立見さんが結果を報告されてますね。
遅くなる実装があるようです
GCによって親のいないクラスがアンロードされて、Singletonクラスごと
なくなってしまう問題があったと思うが?
→JDK1.1? 以前では、Singletonクラス自身がアンロードされた場合に、
その中のクラス変数が参照していたインスタンスも失われてしまうと
いう問題があったが、これは解消されたという情報を見た気がする。
→http://java-house.jp/ml/archive/j-h-b/028054.html
→この問題については、Javaの格言に記述がある(場所は不明。10行程度)
■Prototype (p.65)
p.69下のコード
nullチェック必要ですよね
→サンプルコードだからか。実際には、protonameがnullの時と、
protonameとして存在しないものの場合との2件、
NullPointerExceptionが起こりうるので、それぞれを表す例外を
投げたりするのでは
Hashtableを使うかHashmapを使うか迷います
→基本的にはInterfaceで持たせるほうが綺麗だが、特定の実装にある
メソッドを使う場合には(ダウンキャストを避けるためにも)クラスを
書くこともある
p.70下
clone()って書きます? あまり使わないけど
→shallowコピーじゃ困る場合(フィールドにvectorを持っていて、
その先も複製したい場合)には書く
p.72
getBytes()で下線の長さを求めているが、半角カナ等の、画面上の文字幅と
バイト数が一致しない文字列が来た場合にずれるのでは?
→表示幅とbyte数が同じことを前提にしたサンプルになっているようだ
→AWT等ではフォント幅を計算してそろえるが、コンソールプログラム
ではどうするのか。表示幅を求めるAPIはあるのか?
-------
■昼休み
二手に分かれて昼食を取った。中華料理屋の方で出た話題は
- オージスのUML検定の話
- デザインパターンの雛型を作ってくれるUMLエディタなど
- J2EEの15のデザインパターンの
- AspectJでトレースを埋め込む話
- log4j使ってるよという話
- ステップ数測定ツール、メトリクス測定ツール
-------
再開
Prototypeパターンを使いたくなるようなシーンが思いつきにくい
→グラフィカルなエディタ
→作成したものを元に、コピーしたりするとき
→Beanエディタとかで使ってるんではないか?
→色々な状態を持つインスタンスを生成する際に、毎回初期値を
たくさん与えるのがたいへんな場合に使えるのでは
前章のSingletonのところで、Prototypeが関連しているパターンと
してあげられているが、これは何?
→ManagerをSingletonにするとか、Managerが持つマスターのインス
タンスをSingletonにするとかではないか。必ずそうするというも
のではない。
cloneに関して。全部のフィールドをコピーするcloneを書いたことが
あるが、superを呼んで差分のところだけを書き換えれば良かったと
思っている。
→deep copyしたいところもshallow copyしてから上書きすることに
なるから、無駄といえば無駄
→Javaの格言に、super.clone()は呼ぶなと書いてなかったっけ? □要確認
■Builder (p.81)
HTMLとTextで、getResult()で違うものを返しているから、交換可能
性という点でこのサンプルは弱いのでは
→第3刷(2001年11月1日発行)では、ベースのBuilderでgetResult()
せず、close()というメソッドになっている。結果の取り出しは
個々のサブクラスが持つメソッドで行うようにしたようだ。
サンプルのBuilderでは、titleや本文を作成するメソッドが順番に
実施されることが前提になっている。make*()よりset*()という形に
して、自由な順番で与えて、最後に取り出すときに作成するように
したほうが、使いやすいのではないか
→HTMLBuilderでは、makeTitle()の中でWriterの生成をしたりして
いる。これだと呼ばれる順番に強く依存してしまう
Builderと前のPrototypeと、クラス図はあまり違うように見えない
が、どう違うのか
→Builderは生成の手続きについて隠蔽するという目的がある
→実際には、もっと複数のクラスからnewしたものを関連付けて組み
上げたものを返すようなイメージなのではないか。サンプルは簡単
すぎて、Prototypeとクラス図が似てしまったのでは。
問題7-2
あまりデザインパターンと関係ない設問では。回答もちょっと納得
いかない。まだ例外を投げたほうがいいと思う
問題7-4もデザインパターンとは無関係。Javaのテクニック的な話で
はあるが
■Abstract Factory (p.95)
p.103
PageクラスにmakeHTML()があるが、これはItemクラスのmakeHTML()と
無関係で、名前が同じというだけなんですね
p.117
具体的な工場はSingletonパターンになることがある、とあるが、実際
どう作るのか
→getFactory()でチェックして二つ作らないようにするとか
p.115
UML図でCreatesのところは、実線(関連)ではなく点線ではないか
→フィールドで持つなら実線で、newして返すだけなら点線だと思っていた
→Javaでマップする時にどれが正しいという話はあるのだろうか □要確認
→Createsという関連名は一般的なものか、この本独自のものか □要確認
実際にこういうHTMLを作るなら、こういうやりかたはしないよね
→XSLTを使う
→Jakarta Velocityはどう?
→C#で動作環境宣言をすると、printlnの出力先がコンソールに
なったりHTMLになったり切り替わる
Factory Methodの集まったものがAbstract Factoryなのか?
→類似性のある二つ以上のフレームワークを切り替えるという
ところが主眼
→Abstract Factoryの中にFactory Methodを使っているところが
あると思うが?
→二つのパターンのスコープが違う。注目するところが違う。
まったく同じではないフレームワークの切り替え時に、片方にしかない
機能を提供するようにした場合、難しさがある。
(よくわかりませんでした。よろしければ解説願います 秋元) □
問題8-1の回答
privateにした場合の悪い点で言っていることは、良い事なのでは?
問題8-4
継承については、Peter Coadによる、継承すべきかどうかのチェック
リストを見てみるとよい
■Bridge (p.121)
そうはいっても、CountDisplayにまったく新しい機能を追加したら、
あらたな実装メソッドが必要になるのでは?
→DisplayImplに空のメソッドを追加して、その実装をサブクラスで
書いて対処するのだろうか
Displayクラスのopen(), print(), close()などはpublicより
protectedのほうがよいのではないか。勝手な順番で他から呼ばれるのを
防ぐことができる
問9-3の回答 チェシャ猫の例はよくわからない
→元々のパターン提唱者(J.Carolan)がこの例を持ち出したということで、
そこの文をあたってみないと理解できないのかも
■次回予定
2002.1.19(土) or 1.26(土) 場所未定
[ 戻る ]