シングルトンパターン
CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 65/87。
Singleton Pattern(シングルトンパターン)は、アプリケーション全体でクラスのインスタンスが1つだけであることを保証し、そのインスタンスへのグローバルなアクセスポイントを提供する生成に関するデザインパターンです。これは、設定マネージャー、コネクションプール、ロギングサービスのように、共有すべきリソースに役立ちます。
このパターンは、コンストラクタをprivateにして直接のインスタンス化を防ぐことで機能します。代わりに、静的メソッドが唯一のインスタンスへのアクセスを制御します。
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() を呼び出すたびに、同じオブジェクトが返されます。インスタンスは最初にリクエストされたときにのみ作成されます。これは遅延初期化(lazy initialization)と呼ばれます:
DatabaseConnection db1 = DatabaseConnection.getInstance();
DatabaseConnection db2 = DatabaseConnection.getInstance();
System.out.println(db1 == db2); // true - 同一のインスタンスSingletonの主要な構成要素は次のとおりです:インスタンスを保持するprivate staticフィールド、privateコンストラクタ、そしてインスタンスを返すpublic staticメソッドです。この組み合わせにより、オブジェクトを何度リクエストしても、常に同じオブジェクトが返されることが保証されます。
チャレンジ
簡単シングルトンパターンを使用して、アプリケーションの構成マネージャーを構築しましょう!構成マネージャーは、アプリケーションのすべての部分が、何度アクセスを要求しても同じ設定を共有することを保証します。
コードは2つのファイルに分けて構成します:
AppConfig.java: アプリケーションの構成設定を管理するシングルトンクラスを作成します。AppConfigには以下を含める必要があります:単一のインスタンスを保持するための private static フィールド。
appNameという名前の private String フィールドと、maxUsersという名前の private int フィールド。appNameを"MyApplication"に、maxUsersを100に初期化し、AppConfig initializedと出力する private コンストラクタ。インスタンスがまだ存在しない場合にのみ作成し(遅延初期化)、それを返す public static な
getInstance()メソッド。アプリ名を更新する
setAppName(String name)メソッド。最大ユーザー数を更新する
setMaxUsers(int max)メソッド。App: [appName], Max Users: [maxUsers]と出力するdisplaySettings()メソッド。Main.java: シングルトンが正しく動作することを実証してください!新しいアプリ名(String)と新しい最大ユーザー数(integer)の2つの入力を受け取ります。まず、
AppConfigのインスタンスを取得し、config1という変数に格納します。displaySettings()を呼び出してデフォルト値を表示します。次に、
config1に対してsetAppNameとsetMaxUsersを呼び出し、入力値を使用して設定を更新します。別のインスタンスを取得して
config2に格納します。config2でdisplaySettings()を呼び出し、config1を通じて行われた変更が反映されていることを証明します。最後に、
config1 == config2を比較して、両方の参照が同じオブジェクトを指しているかどうかをSame instance: [true/false]の形式で出力します。
入力は、新しいアプリ名(String)、新しい最大ユーザー数(integer)の順に2つ受け取ります。
このチャレンジは、シングルトンパターンの核心的な利点を示しています。構成を何度要求しても、常に同じ共有状態を持つ同じインスタンスを取得できるのです!
チートシート
シングルトンパターン(Singleton Pattern)は、アプリケーション全体でクラスのインスタンスが1つだけであることを保証し、そのインスタンスへのグローバルなアクセスポイントを提供します。
主な構成要素:
- 唯一のインスタンスを保持する
private staticフィールド - 直接のインスタンス化を防ぐための
privateコンストラクタ - インスタンスを返す
public staticメソッド
基本的な実装:
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);
}
}使用例:
DatabaseConnection db1 = DatabaseConnection.getInstance();
DatabaseConnection db2 = DatabaseConnection.getInstance();
System.out.println(db1 == db2); // true - 同じインスタンスインスタンスは最初にリクエストされたときにのみ作成されます。これは遅延初期化(lazy initialization)と呼ばれます。getInstance() を呼び出すたびに同じオブジェクトが返されるため、アプリケーション全体で状態が共有されることが保証されます。
自分で試してみよう
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: 両方の参照が同じオブジェクトを指しているかを出力する:
// config1 == config2 を使用して "Same instance: [true/false]" と出力する
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4継承
継承の基本 (extends)super キーワードメソッドのオーバーライド (@Override)コンストラクタチェーンObject クラス単一継承と多段階継承なぜ多重継承ができないのかまとめ:従業員の階層構造