[戻る]
Java読書会BOF「Practical Design Patterns for Java Developers」を読む会 第3回¶
場所 |
てくのかわさき 談話室 |
出席者(敬称略) |
高橋(智)、根本、高橋(徹) |
本日は、p.63「第2部 Implementing Standard Design Patterns Using Java Programmingから
Part 2: Implementing Design Patterns Using Java Programming¶
第3章 生成に関する設計パターン¶
本章のサンプルコードは github から入手可能
(個人メモ)newをしないでオブジェクトを生成する
ファクトリメソッドパターンを使用した入力に基づいたオブジェクトの作成¶
Executors ユーティリティクラスの newFixedThreadPoolメソッドとは?
引数で指定したスレッド数とプールとして使用する Executorを生成するメソッド
図3.2 UML図で VehicleFactoryクラスのproduceメソッドが戻り値型を書いていないがいいのか?
UML図では、メソッド名以外の可視性、引数、戻り値は省略可能
例3.5 record型を使った実装
record型の宣言で型名の後ろに括弧内に列挙した型・変数がフィールドとして生成
record型はイミュータブル、hashcode, equals, toString, フィールドのgetterメソッドが自動で生成。getterメソッド名はフィールド名と同じ。
抽象ファクトリパターンを使用してさまざまなファミリからオブジェクトを作成する¶
ビルダーパターンを使用した複雑なオブジェクトのインスタンス化¶
機械翻訳では、文章中の クラス名.メソッド名の ピリオドが文章の終端のピリオドとして翻訳され、文章がかなり怪しいものになってしまう。
例3.10のコード中の slowVehicleが機械翻訳でthrowVehicleに書き換えられている!
ビルダーパターンの実装として2つの方法が記載されている
slowVehicleの生成では、ビルダーのロジックをメソッド内にまとめている
fastVehicleの生成では、メソッドチェーンで属性を指定する(よく見るビルダーパターンの実装)
p.78の Conclusionの2段落目、"to use the JVM's heap or stack - more specifically, to create a statically or dynamically..."が意味するところが不明
著者がrecord型がスタックに置かれると勘違いしている可能性あり
プロトタイプパターンを使用したオブジェクトのクローン作成¶
例3.13のコードは、github上のサンプルコードに対して2行不足しているので、次の実行結果の表示と整合していない。
equalsがfalseになるのは、Vehicleクラスの実装でequalsがオーバーライドされていないため、Object型のequalsが実行されるため
宿題)record型をcloneできるか? cloneした場合、equalsはtrueになるかfalseか?
Javaでのcloneの作法を復習する必要ありそう
例3.13 で、cloneをするには、VehicleクラスでCloneableの実装に加えて、publicなcloneを実装する必要あるが、サンプルコードではprotectedになっている。 サンプルはmainも含めて全て同じパッケージにつっこんでいるのでこれでも動作するが、本来は違う。
例3.16で、cloneは抽象クラスVehicleに実装されており、それはObject型のcloneを呼んでいる。この場合、StringフィールドがシャロウコピーされるがStringはイミュータブルなので問題なし
シングルトンパターンでインスタンスを1つだけ確保する¶
誤植 図3.6 OnlyVehicleクラスの中のgetInstanceの戻り値型が OnlineVehicle -> OnlyVehicle
例3.17のコードは、シングルトンで取得したEngineインスタンスをequalsで比較しているが、同じインスタンスが返ってくるので、==で比較すれば良いのでは?
.formatted(engine, vehicle.getEngine() == engine) でよくないか?
例3.20のコードは、上3行が、OnlyEngineEnum.javaの実装で、その後のコード断片は、OnlyVehicle.javaの中の一部分でコンストラクタの実装。
宿題)マルチスレッド下でも今ならば、普通にsynchronizedまたはロックオブジェクトでブロックしてもいいのではないか?
性能差があるのか?
p.85 結論で、単一責任の範囲がどこか不明確なので意図が読みづらい。オブジェクトの生成と、オブジェクトの振る舞いは責務が別とみなすと文の意図は通るが、そこまで責務を分けるべきということか?
オブジェクトプールパターンでパフォーマンスを改善する¶
遅延初期化パターンを使用してオンデマンドでオブジェクトを開始する¶
p.90 下5行目 -> は何を指しているのか?
【誤植】図3.8 VechicleProvider型のgetVehicleByTypeメソッドの戻り値型がtypeになっているが、Vehicle型の誤植
【誤植】例3.25 mainメソッドの最終行、car1.equals(car2)は、car1 == car2 の誤り
LazyVehicleクラスの意義がよく分からない
依存性注入パターンによるクラスの依存関係の削減¶
宿題)JavaのServiceLoaderを使った振る舞いを理解しよう
参考URL
META-INF/services/ の下に置くファイルは、インタフェースのFQCNで、ファイルの中身は実装クラスのFQCN
ファイルには複数の実装クラスのFQCNを行ごとに記述可能
loadの戻り値(ServiceLoader)は Iterableなので、記述した実装クラスの数だけイテレートできる
ServiceLoaderは、JPMS(Java Platform Module System)では、META-INF/servicesではなく、module-info.javaに記述する
まとめ¶
Q1. 生成と振る舞いを分離し単一責任を促進 Q2. オブジェクトプール、遅延初期化 Q4. プロトタイプパターン、ビルダーパターンも? Q5. アブストラクトファクトリーパターン、ビルダーパターン、プロトタイプパターン Q6. Yes。オブジェクトプール(一度作ったものの使い回し)、遅延初期化(使わないものは生成しない) Q7. アブストラクトファクトリパターン
本日は、p.100 まで読み終わりました。 次回は、p.101 第4章 構造に関するデザインパターン
[戻る]