デザインパターンの中で、個人的には一番メジャーな気がする、「シングルトンパターン」をやってみます。
シングルトンパターンってなに?
1つのアプリケーション内に、1つしかインスタンスを持たないクラスを言います。
データを共有したかったり、処理の同期を取りたかったりするときに使用します。
シングルトンパターンのサンプル
さっそくですが、シングルトンパターン基本形のサンプルです。
シングルトンパターンのクラスから、インスタンスを2つ取得。
いずれか一方を改変すると、他方でも改変されます。
これにより、シングルトンパターンのクラスから取得したインスタンスは、同一であることが確認できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public class SingletonTest { private static SingletonTest instance = null; private String hoge = null; private SingletonTest() { } public static SingletonTest getInstance() { if(instance == null) { instance = new SingletonTest(); } return instance; } public String getHoge() { return hoge; } public void setHoge(String hoge) { this.hoge = hoge; } public static void main(String[] args) { SingletonTest test1 = SingletonTest.getInstance(); SingletonTest test2 = SingletonTest.getInstance(); test1.setHoge("hogehoge value"); System.out.println("test1#getHoge() : " + test1.getHoge()); System.out.println("test2#getHoge() : " + test2.getHoge()); } } |
実行結果
1 2 | test1#getHoge() : hogehoge value test2#getHoge() : hogehoge value |
マルチスレッドへの対応
上記の基本形はスレッドセーフではなく、複数のスレッドで動作すると思った通りに動作しない可能性があります。
マルチスレッドを考慮して、以下のように書き換えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | public class SingletonTest2 { private static SingletonTest2 instance = null; private String hoge = null; private SingletonTest2() { } public static SingletonTest2 getInstance() { //ホルダーからインスタンスを取得して、そのまま返却 return SingletonTest2Holder.instance; } public String getHoge() { return hoge; } public void setHoge(String hoge) { this.hoge = hoge; } private static class SingletonTest2Holder { //ホルダーにインスタンスを静的に保持。・・・ホルダーを初めて触った瞬間にインスタンスを作成。 private static final SingletonTest2 instance = new SingletonTest2(); } public static void main(String[] args) { SingletonTest2 test1 = SingletonTest2.getInstance(); SingletonTest2 test2 = SingletonTest2.getInstance(); test1.setHoge("hogehoge value"); System.out.println("test1#getHoge() : " + test1.getHoge()); System.out.println("test2#getHoge() : " + test2.getHoge()); } } |