Create Branch

オブジェクト生成の課題と解決策

Published on 2025年9月27日

オブジェクト指向

はじめに

オブジェクト指向ベースで個人開発を進めていく中で、「インスタンス生成はどう管理するべきか?」という疑問にぶつかったので、現段階の認識した情報の中でどのようにより扱うかを決めました。

思考整理も兼ねて、現在の認識を言語化しました。

背景

最初は「クラスを使う側でnewればいいじゃん」と考えていたら、カプセル化の概念を考えたとき、インスタンス化がクライアント側で行われることに違和感を感じた。
インスタンス化をどのように取り扱うべきか、悩んだのでここを言語化したい。 また、構造上どのように定義するべきか誤った認識のもと、開発を進めていくことになると考えた。
この違和感を感じた状態の払拭しつつ、誤った方向性で進めないために解像度を高めたい。

問題の発端:外部でのインスタンス生成の課題

よくある実装パターンとその問題点

クライアント側で直接具象クラスをインスタンス化するパターンです。

// よくある実装(問題あり)
public static void Main() {
    // フォント設定が必要になった場合...
    string fontName = GetFontNameFromConfig();
    int fontSize = GetFontSizeFromConfig();

    // クライアント側で具象クラスを直接生成
    Document[] documents = {
        new PDFDocument(),
        new WordDocument(fontName, fontSize),
        new ExcelDocument()
    };

    foreach (var document in documents) {
        ProcessDocument(document);
    }
}


この実装の何が問題なのか?

1. カプセル化の破綻 オブジェクト生成ロジックがクラス外部に散らばることで、本来クラス内部で管理すべき初期化の詳細が外部に露出してしまいます。

2. 密結合の発生 クライアントコードが具体的なクラスに直接依存するため、システムの柔軟性が大幅に損なわれます。

3. 重複した初期化ロジック 複雑な初期化処理が必要な場合、同じようなコードが複数箇所に散在し、保守性が悪化します。

4. テスタビリティの低下 具体クラスへの直接依存により、モックやスタブを使った単体テストが困難になります。

ファクトリーパターンによる解決

疎結合な構造への変換

ファクトリーパターンを導入することで、以下のような構造に変更できます

ファクトリーパターンの利点

変更に強いシステム

  • 新しい決済方法(例:暗号通貨決済)を追加する場合、クライアントコードを変更する必要がありません
  • ファクトリーと新しい具象クラスを追加するだけで機能拡張が可能

保守性の向上

  • オブジェクト生成ロジックが一箇所に集約される
  • 設定変更や初期化ロジックの修正時の影響範囲が限定される

テスタビリティの向上

  • インターフェースを通じてモックオブジェクトを簡単に注入できる

なぜ疎結合が重要なのか?

疎結合の真の価値は変更への対応力にあります。

例えば、決済処理システムで新しい決済方法を追加する場合

  • 密結合な設計:全てのクライアントコードを修正する必要がある
  • 疎結合な設計:ファクトリーと新しい具象クラスを追加するだけ

これにより、「そのクラスだけを見直せば良い」状態を実現できます。

学んだこと:ファクトリーパターンの本質

ファクトリーパターンで解決したい課題 使用するプロダクトクラスをクライアント側に依存させない状態を作り、プロダクトクラスの拡張性・変更容易性を高めて変更に強い状態にすること。

結論

最初は「ファクトリーパターンを取り入れるかどうか悩んでいた」状態でしたが、学習を通じて最初から導入する価値があることを理解しました。

特に以下のような場面では、ファクトリーパターンの導入を強く推奨します。

  • 複数の類似した機能を持つクラスがある
  • 将来的に機能拡張の可能性が高い
  • テストしやすいコードを書きたい
  • 保守性を重視したい

オブジェクト指向設計において、「どこで何を生成するか」は思った以上に重要な設計判断です。ファクトリーパターンを理解することで、より柔軟で保守しやすいコードが書けるようになります。


hirotobeat