デザインパターン > シングルトン(Singleton) シングルトン(Singleton) - GoF †Singletonパターンはあるクラスのインスタンスが1つであるように制限する為のデザインパターン。 「インスタンスが個別に”状態”を持たない場合で、無駄なインスタンス生成を避けたい場合」や、逆に「ある単一のインスタンスの状態を操作、参照したい場合」に有効。 ◆Singletonでない処理 /* メイン処理クラス // public Class NormalClass { public static void main(String[] args) { int a = 10; int b = 5; NormalUtil util1 = new NormalUtil(); System.Out.Println(util1.addition(a, b)); NormalUtil util2 = new NormalUtil() System.Out.Println(util2.subtraction(a, b)); NormalUtil util3 = new NormalUtil() System.Out.Println(util3.multiplication(a, b)); } } /* 演算用ユーティリティクラス */ public Class NormalUtil{ public int addition(int a , int b) { return a + b; } public int subtraction(int a , int b) { return a - b; } public int multiplication(int a , int b) { return a * b; } } 上記の例では、NormalUtilを使用しているが、同じNormalUtilのインスタンス生成を3度も行っている。 この処理を、Singleton にすると下記のようになる。 ◆Singletonな処理 /* メイン処理クラス */ public Class NormalClass { public static void main(String[] args) { int a = 10; int b = 5; SingletonUtil util1 = SingletonUtil.getInstance() System.Out.Println(util1.addition(a, b)); SingletonUtil util2 = SingletonUtil.getInstance() System.Out.Println(util2.subtraction(a, b)); SingletonUtil util3 = SingletonUtil.getInstance() System.Out.Println(util3.multiplication(a, b)); } } /* 演算用ユーティリティクラス */ public Class SingletonUtil{ /* インスタンスを格納する変数(privateなので外部からの設定は不可) */ private static SingletonUtil instance = null; /* コンストラクタ(外部からのインスタンス生成を禁止する為 protected にする) */ protected SingletonUtil() { } /* 単一のインスタンスを取得する為のメソッド */ public static SingletonUtil getInstance() { if (instance == null) { instance = new SingletonUtil(); } return instance; } public int addition(int a , int b) { return a + b; } ・ ・ } 上記のように Singleton にする事によって、確実に無駄なインスタンス生成が行われないように制限をかける事ができる。 ただし、上記のコードにマルチスレッドに対応していない。 これを解決する(マルチスレッドに対応する)には、SingletonUtil を以下のように変更する。 /* 演算用ユーティリティクラス */ public Class SingletonUtil{ private static class InstanceHolder { public static SingletonUtil instance = new SingletonUtil(); } /* コンストラクタ(外部からのインスタンス生成を禁止する) */ private SingletonUtil() {} /* 単一のインスタンスを取得する為のメソッド */ public static SingletonUtil getInstance() { return InstanceHolder.instance; } ・ ・ } 上記は Initialize-On-Demand Holder というイディオムで、マルティスレッド環境でシングルトンなインスタンスを安全 かつ シンプルに生成する。 |