【ITニュース解説】Thoughts on object creation
2025年09月04日に「Dev.to」が公開したITニュース「Thoughts on object creation」について初心者にもわかりやすいように丁寧に解説しています。
ITニュース概要
オブジェクト作成時の課題とGoFのCreational Patternsの活用法を解説。 同じ型が連続するコンストラクタ引数の間違いを防ぐType Wrappers、JavaにないNamed Parameters、複雑なオブジェクト生成を助けるBuilder Patternを紹介。 コンストラクタ内での例外処理を避け、Factory Methodでオブジェクトの初期化を確実にする手法も解説する。
ITニュース解説
この記事では、オブジェクトの作成における課題と、それを解決するためのデザインパターンについて解説する。特に、GoF(Gang of Four)のデザインパターンの中でも、オブジェクトの生成に関するパターンに着目し、具体的なJavaのコード例を交えながら、その適用方法と利点、注意点を示す。
まず、多くの引数を持つコンストラクタの問題点が指摘される。例えば、Licenseクラスのコンストラクタが多数のString型引数を持つ場合、引数の順序を間違える可能性が高まる。
1public License ( 2 String id, String licenseeName, 3 String licenseId, String environment, 4 LocalDateTime generatedAt 5)
この問題を解決する一つの方法として、型ラッパーの利用が提案される。各引数を専用の型でラップすることで、コンパイル時に型チェックが可能となり、引数の順序間違いを防ぐことができる。
1public record Id(String id) { ... } 2public record LicenseeName(String licenseeName) { ... } 3public record LicenseeId(String licenseId) { ... } 4public record Environment(String environment) { ... } 5public record GeneratedAt(LocalDateTime generatedAt) { ... }
ただし、型ラッパーはメモリ消費量を増加させる可能性がある。Kotlinのインラインクラスを利用すれば、コンパイル時のチェックは行いつつ、実行時のオーバーヘッドを抑えることができる。
次に、名前付きパラメータの利用が挙げられる。Javaでは提供されていない機能だが、Kotlinなどの言語では、コンストラクタ呼び出し時に引数名を指定できるため、引数の順序を気にせずにコードの可読性を向上させることができる。
さらに、Builderパターンが紹介される。Builderパターンは、複雑なオブジェクトの生成プロセスを隠蔽し、クライアントがオブジェクトの構成要素を一つずつ指定できるようにする。
1public class License { 2 // ... 3 public static class LicenseBuilder { 4 // ... 5 public LicenseBuilder withId(String id) { 6 this.id = id; 7 return this; 8 } 9 // ... 10 public License build() { 11 return new License(id, licenseeName, licenseId, environment, generatedAt); 12 } 13 } 14}
Builderパターンを利用することで、オブジェクトの生成コードがより読みやすくなり、各メソッド呼び出し時にバリデーションを追加することも可能となる。ただし、Builderクラスの作成には手間がかかるというデメリットもある。
記事では、コンストラクタ内で例外をスローすることの問題点にも触れている。コンストラクタ内で例外が発生した場合、リソースリークや継承の問題が発生する可能性がある。
1public Stuff(UuidService uuidService, FallbackUuidService fallbackUuidService) { 2 try { 3 uuid = uuidService.getUuid(); 4 } catch(CannotGetUuidException e) { 5 // ... 6 } 7}
この問題を解決するために、Factory Methodパターンが提案される。Factory Methodパターンは、オブジェクトの生成を専門のメソッドに委譲し、コンストラクタ内での例外発生を避けることができる。
1public class Stuff { 2 private Stuff(UUID uuid) { 3 this.uuid = uuid; 4 } 5 6 public static Stuff create(UuidService uuidService, FallbackUuidService fallbackUuidService) throws CannotGetUuidException { 7 try { 8 return new Stuff(uuidService.getUuid()); 9 } catch(CannotGetUuidException e) { 10 return new Stuff(fallbackUuidService.getUuid()); 11 } 12 } 13}
Factory Methodパターンを利用することで、オブジェクトが完全に初期化されるか、例外が発生してオブジェクトが作成されないかのどちらかになるため、安全なオブジェクト生成が可能となる。
最後に、GoFのデザインパターンは、当初想定された用途以外にも、コードの保守性向上やオブジェクトの安全な初期化など、様々な場面で役立つことが強調される。古典的な知識を習得することで、現代のソフトウェア開発における課題解決に役立てることができる。