Singletonパターン

## 1. Singleton パターンとは？

- **定義**: クラスのインスタンスが1つだけ生成され、グローバルにアクセス可能にするデザインパターン
- **目的**: リソースの共有や一意性を保証（例：設定管理、ロギング）
- **カテゴリ**: 生成パターン（Creational Pattern）

## 2. どんな時に使う？

- アプリケーション全体で1つのインスタンスのみが必要な場合
- グローバルなアクセスポイントを提供したい場合
- リソースの重複生成を防ぎたい場合（例：データベース接続、ログ管理）

## 3. 構造

- **Singletonクラス**: 自身のインスタンスを管理し、外部からの直接インスタンス化を制限
  - プライベートなコンストラクタ
  - 静的フィールドで自身のインスタンスを保持
  - 静的なメソッドでインスタンスを提供

## 4. サンプルコード（Java）

以下は、シングルトンパターンを使用したログ管理クラスの例です。

### Singletonクラス

```java
public class Logger {
    // 唯一のインスタンスを保持
    private static Logger instance = null;
    
    // プライベートコンストラクタで外部からのインスタンス化を防止
    private Logger() {
        // インスタンス化防止のための空コンストラクタ
    }
    
    // インスタンスを取得する静的メソッド（スレッドセーフ）
    public static synchronized Logger getInstance() {
        if (instance == null) {
            instance = new Logger();
        }
        return instance;
    }
    
    // ログを出力するメソッド
    public void log(String message) {
        System.out.println("Log: " + message);
    }
}
```

### クライアントコード

```java
public class Main {
    public static void main(String[] args) {
        Logger logger1 = Logger.getInstance();
        Logger logger2 = Logger.getInstance();
        
        logger1.log("First message");
        logger2.log("Second message");
        
        // 同一インスタンスであることを確認
        System.out.println("Same instance? " + (logger1 == logger2)); // true
    }
}
```

## 5. メリット

- **一意性の保証**: インスタンスが1つだけであることを保証
- **リソース節約**: 複数インスタンスの生成を防ぎ、メモリを節約
- **グローバルアクセス**: どこからでも同じインスタンスにアクセス可能

## 6. デメリット

- **グローバル状態**: グローバル変数のような振る舞いがテストや保守を難しくする
- **スレッドセーフ問題**: マルチスレッド環境では同期処理が必要（例：上記の`synchronized`）
- **拡張性の制約**: シングルトンは継承や柔軟な変更が難しい

## 7. 実際の使用例

- ロギングシステム（例：ログファイルへの単一アクセス）
- データベース接続プール
- アプリケーション設定の管理
- キャッシュ管理

## 8. 注意点

- **スレッドセーフ**: マルチスレッド環境では、初期化を安全にする方法（例：Double-Checked LockingやInitialization-on-Demand Holder）が必要
- **テストの難しさ**: シングルトンは状態を保持するため、単体テストが複雑になる場合がある
- **代替案**: 依存性注入（DI）を使うことで、シングルトンの必要性を減らせる場合も

## 9. まとめ

- Singletonは、1つのインスタンスを共有しグローバルアクセスを提供する際に有効
- 適切な場面で使用すればリソース効率が向上
- スレッドセーフやテスト容易性に注意し、乱用は避ける！

<details><summary>この記事のMarkdown</summary>

~~~markdown
# Singleton パターン

## 1. Singleton パターンとは？

- **定義**: クラスのインスタンスが1つだけ生成され、グローバルにアクセス可能にするデザインパターン
- **目的**: リソースの共有や一意性を保証（例：設定管理、ロギング）
- **カテゴリ**: 生成パターン（Creational Pattern）

## 2. どんな時に使う？

- アプリケーション全体で1つのインスタンスのみが必要な場合
- グローバルなアクセスポイントを提供したい場合
- リソースの重複生成を防ぎたい場合（例：データベース接続、ログ管理）

## 3. 構造

- **Singletonクラス**: 自身のインスタンスを管理し、外部からの直接インスタンス化を制限
  - プライベートなコンストラクタ
  - 静的フィールドで自身のインスタンスを保持
  - 静的なメソッドでインスタンスを提供

## 4. サンプルコード（Java）

以下は、シングルトンパターンを使用したログ管理クラスの例です。

### Singletonクラス

```java
public class Logger {
    // 唯一のインスタンスを保持
    private static Logger instance = null;
    
    // プライベートコンストラクタで外部からのインスタンス化を防止
    private Logger() {
        // インスタンス化防止のための空コンストラクタ
    }
    
    // インスタンスを取得する静的メソッド（スレッドセーフ）
    public static synchronized Logger getInstance() {
        if (instance == null) {
            instance = new Logger();
        }
        return instance;
    }
    
    // ログを出力するメソッド
    public void log(String message) {
        System.out.println("Log: " + message);
    }
}
```

### クライアントコード

```java
public class Main {
    public static void main(String[] args) {
        Logger logger1 = Logger.getInstance();
        Logger logger2 = Logger.getInstance();
        
        logger1.log("First message");
        logger2.log("Second message");
        
        // 同一インスタンスであることを確認
        System.out.println("Same instance? " + (logger1 == logger2)); // true
    }
}
```

## 5. メリット

- **一意性の保証**: インスタンスが1つだけであることを保証
- **リソース節約**: 複数インスタンスの生成を防ぎ、メモリを節約
- **グローバルアクセス**: どこからでも同じインスタンスにアクセス可能

## 6. デメリット

- **グローバル状態**: グローバル変数のような振る舞いがテストや保守を難しくする
- **スレッドセーフ問題**: マルチスレッド環境では同期処理が必要（例：上記の`synchronized`）
- **拡張性の制約**: シングルトンは継承や柔軟な変更が難しい

## 7. 実際の使用例

- ロギングシステム（例：ログファイルへの単一アクセス）
- データベース接続プール
- アプリケーション設定の管理
- キャッシュ管理

## 8. 注意点

- **スレッドセーフ**: マルチスレッド環境では、初期化を安全にする方法（例：Double-Checked LockingやInitialization-on-Demand Holder）が必要
- **テストの難しさ**: シングルトンは状態を保持するため、単体テストが複雑になる場合がある
- **代替案**: 依存性注入（DI）を使うことで、シングルトンの必要性を減らせる場合も

## 9. まとめ

- Singletonは、1つのインスタンスを共有しグローバルアクセスを提供する際に有効
- 適切な場面で使用すればリソース効率が向上
- スレッドセーフやテスト容易性に注意し、乱用は避ける！
~~~

</details>