Menu
Coddy logo textTech

シングルトンパターン

CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 65/87。

Singleton Patternは、アプリケーション全体でクラスのインスタンスが1つだけ存在することを保証し、そのインスタンスへのグローバルなアクセスポイントを提供する生成デザインパターンです。これは、設定マネージャー、接続プール、ロギングサービスなど、共有すべきリソースに役立ちます。

このパターンは、constructorをprivateにすることで機能し、directなinstantiationを防ぎます。代わりに、staticメソッドが単一のinstanceへのaccessを制御します。

public class DatabaseConnection {
    private static DatabaseConnection instance;
    
    // プライベートコンストラクタは直接のインスタンス化を防ぎます
    private DatabaseConnection() {
        System.out.println("Connection created");
    }
    
    // グローバルアクセスポイント
    public static DatabaseConnection getInstance() {
        if (instance == null) {
            instance = new DatabaseConnection();
        }
        return instance;
    }
    
    public void query(String sql) {
        System.out.println("Executing: " + sql);
    }
}

getInstance() の呼び出しはすべて同じオブジェクトを返します。instance は最初に要求されたときにのみ作成されます。これはlazy initializationと呼ばれます。

DatabaseConnection db1 = DatabaseConnection.getInstance();
DatabaseConnection db2 = DatabaseConnection.getInstance();

System.out.println(db1 == db2);  // true - same instance

Singletonの主要な構成要素は、instanceを保持するprivate staticフィールド、privateコンストラクター、そしてinstanceを返すpublic staticメソッドです。この組み合わせにより、オブジェクトを何度要求しても、常に同じものを取得することが保証されます。

challenge icon

チャレンジ

簡単

シングルトンパターンを使って、アプリケーションの設定マネージャーを構築しましょう!設定マネージャーによって、アクセスを要求する回数に関係なく、アプリケーションのすべての部分で同じ設定を共有できるようにします。

コードを2つのファイルに分けて整理します。

  • AppConfig.java:アプリケーションの設定を管理するシングルトン class を作成します。AppConfig には、次の要素を用意します。

    単一の instance を保持する private static フィールド。

    appName という名前の private String フィールドと、maxUsers という名前の private int フィールド。

    appName"MyApplication" に、maxUsers100 に初期化し、その後 AppConfig initialized を出力する private constructor。

    instance がまだ存在しない場合にのみ instance を作成する(lazy initialization)public static getInstance() メソッド。その後、instance を返します。

    アプリ名を更新する setAppName(String name) メソッド。

    最大ユーザー数を更新する setMaxUsers(int max) メソッド。

    App: [appName], Max Users: [maxUsers] を出力する displaySettings() メソッド。

  • Main.java:Singleton が正しく動作することを確認します!2つの入力、つまり新しいアプリ名(String)と新しい最大ユーザー数(integer)を受け取ります。

    まず、AppConfig の instance を取得し、config1 という名前の変数に保存します。displaySettings() を呼び出して、デフォルト値を表示します。

    次に、config1 に対して setAppNamesetMaxUsers を呼び出し、入力値を使って設定を更新します。

    別の instance を取得して config2 に保存します。config2 に対して displaySettings() を呼び出し、config1 を通じて行った変更が反映されていることを確認します。

    最後に、config1 == config2 を比較して、両方の参照が同じオブジェクトを指しているかどうかを Same instance: [true/false] として出力します。

入力は順番に2つ受け取ります。新しいアプリ名(String)と新しい最大ユーザー数(integer)です。

このチャレンジでは、シングルトンパターンの中心的な利点を示します。設定を何度要求しても、同じ共有状態を持つ同じ instance が常に返されます。

自分で試してみよう

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 入力を読み取る
        String newAppName = scanner.nextLine();
        int newMaxUsers = scanner.nextInt();
        
        // TODO: AppConfigの最初のインスタンスを取得してconfig1に格納する
        
        // TODO: config1でdisplaySettings()を呼び出してデフォルト値を表示する
        
        // TODO: config1でsetAppNameとsetMaxUsersを使って設定を更新する
        
        // TODO: 別のインスタンスを取得してconfig2に格納する
        
        // TODO: config2でdisplaySettings()を呼び出して変更が共有されていることを証明する
        
        // TODO: 両方の参照が同じオブジェクトを指しているかどうかを出力する:
        // "Same instance: [true/false]" using config1 == config2
    }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Javaオンラインコンパイラ