Menu
CoddyTech

シングルトンパターン

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" に、maxUsers を 100 に初期化し、その後 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 に対して setAppName と setMaxUsers を呼び出し、入力値を使って設定を更新します。

    別の 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オンラインコンパイラ