技術とか戦略とか

証券レガシーシステムを8年いじってから転職した普通の文系SEによるブログ。技術のみではなく趣味の戦略考察についても。

singletonとstaticの違い

デザインパターンのsingletonパターンを学んだ時に「インスタンスを1個にすれば良いなら、クラス変数やメソッドをstaticにすれば良いのでは?」と思ったので、試しにテストコードを書いてみました。
単純なstaticでは利用者側で好きにインスタンスを作成できる(実態としては1つ)のですが、singletonパターンなら利用者側でのインスタンス作成を防ぎ、明示的にインスタンスを1つにできることを確認しました。
 
【テストコード】
・StaticMemory.java
public class StaticMemory {

 private static int num = 0;

 public static void setNum(int arg) {
  num = arg;
 }

 public static int getNum() {
  return num;
 }

}
 
・SingletoneMemory.java
public class SingletoneMemory {

 private static int num = 0;
    private static SingletoneMemory instance = new SingletoneMemory();

    private SingletoneMemory(){
        // インスタンスを生成
    }

    public static SingletoneMemory getInstance(){
        return instance;
    }

 public static void setNum(int arg) {
  num = arg;
 }

 public static int getNum() {
  return num;
 }

}
 
・MemoryTestMain.java
public class MemoryTestMain {

 // 要件:最新の値をメモリに保持したい
 @SuppressWarnings("static-access")
 public static void main(String[] args) {

  int recentNum = 0; // 最新の値

  // 普通のStaticなクラスを使った場合
  recentNum = 1;
  StaticMemory.setNum(recentNum);

  // 使う側がオブジェクトを作れてしまう
  StaticMemory instance1 = new StaticMemory();
  recentNum = 2;
  instance1.setNum(recentNum);

  StaticMemory instance2 = new StaticMemory();
  recentNum = 3;
  instance2.setNum(recentNum);

  // Staticなので実際には何れのオブジェクトも同じアドレスを指す
  System.out.println("元のStaticクラス:"+StaticMemory.getNum());
  System.out.println("作ったオブジェクト1:"+instance1.getNum());
  System.out.println("作ったオブジェクト2:"+instance2.getNum());

  // Singletoneなクラスを使った場合
  // オブジェクトがprivateなので外部から作れない(下記はエラー)
  // SingletoneMemory instance3 = new SingletoneMemory();

  // 唯一のオブジェクトを取得する必要がある
  recentNum = 4;
  SingletoneMemory.getInstance().setNum(recentNum);
  System.out.println
  ("Singletoneクラス:"+SingletoneMemory.getInstance().getNum());

 }

}
 
【実行結果】
元のStaticクラス:3
作ったオブジェクト1:3
作ったオブジェクト2:3
Singletoneクラス:4