技術とか戦略とか

IT技術者が技術や戦略について書くブログです。

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;
 }

}
 
・SingletonMemory.java
public class SingletonMemory {

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

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

    public static SingletonMemory 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());

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

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

 }

}
 
【実行結果】
元のStaticクラス:3
作ったオブジェクト1:3
作ったオブジェクト2:3
Singletonクラス:4
 
-------------------------
 
"Singleton"を"Singletone"とtypoしている箇所があったので直しました。