5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SingletonパターンをJavaとJavaScriptのコードを比較して理解する

Last updated at Posted at 2016-12-25

#はじめに
詳しいことや他のパターンは**デザインパターンをJavaScriptとJavaでの実装を比較して理解する**に書いていきます。

#Singletonパターン
ソフトウェアでは普通、クラスから複数のインスタンスを生成したり、できる状態にしておく
だが、「このクラスのインスタンスはたった1つしか作らないし、作りたくない」という時がある
RPGでの伝説の剣などがそうである
1つのゲーム、オンラインゲームなどで伝説の剣が何個も手に入ってしまっては価値が下がってしまう

  • 指定したクラスのインスタンスが絶対に一個しか存在しなことを保証したい
  • インスタンスが1個しか存在しないことをプログラム上で表現したい

そんなインスタンスが一個しか存在しないことを保証するパターをSingletonパターンと呼ぶ

##Javaでの実装例
###クラス図
コンストラクタがprivateになっているのはnew Singleton()と記述した場合エラーを吐くようにするため
Singleton.png

###コード

Main.java
public class Main {
    public static void main(String[] args) {
        System.out.println("Strat.");
        Singleton obj1 = Singleton.getInstance();
        Singleton obj2 = Singleton.getInstance();
        if (obj1 == obj2) {
            System.out.println("obj1とojb2は同じインスタンスです。");
        } else {
            System.out.println("obj1とobj2は同じインスタンスではありません。");
        }
        System.out.println("End.");
        // 試に以下のコメントを外すとエラーが出る
        // Singleton obj3 = new Singleton();
    }
}
Singleton.java
public class Singleton {
    private static Singleton singleton = new Singleton();

    private Singleton() {
        System.out.println("インスタンスを生成しました。");
    }
    public static Singleton getInstance() {
        return singleton;
    }
}

###インスタンスの生成タイミング
実行結果は以下のようになると思います

Start.
インスタンスを生成しました。
obj1とobj2は同じインスタンスです。
End.

上記でわかるように、初めてgetInstanceメソッドが呼び出された時にインスタンスが生成されていることがわかる
Singletonクラスが読み込まれるのはgetInstance静的メソッドが呼び出された時である
##JavaScriptでの実装例
###コード

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Singleton</title>
    <script src="Main.js"></script>
    <script src="Singleton.js"></script>
</head>
<body>
    
</body>
</html>
Main.js
var MAIN = {};

MAIN.init = function() {
    console.log("Start.");
    /**
     * 本には以下のように記述してありましたが、比較しやすいように変更しました
     * var obj1 = SINGLETON.singleton
     * var obj2 = SINGLETON.singleton
     */
    var obj1 = SINGLETON.singleton.getInstance();
    var obj2 = SINGLETON.singleton.getInstance();
    if (obj1 === obj2) {
        console.log("obj1とobj2は同じインスタンスです。");
    } else {
        console.log("obj1とobj2は同じインスタンスではありません。");
    }
    console.log("End.");
};

window.addEventListener("load", MAIN.init);
Singleton.js
var SINGLETON = {};

SINGLETON.singleton = (function() {
    var instance;

    function init() {
        console.log("インスタンスを生成しました。");
        var privateVariable = "I am also private";
        function privateMethod() {
            console.log("I am private");
        }

        return {
            publicProperty: "I am also public",
            publicMethod: function() {
                console.log("The public can ses me!");
            }
        };
    };

    return {
        getInstance: function() {
            if (!instance) {
                instance = init();
            }

            return instance;
        }
    };
})();

##Singletonパターンの登場人物

###Singletonの役
唯一のインスタンスを得るためのstaticメソッドを持っている
このメソッドはいつも同じインスタンスを返す

##Singletonのクラス図
Singleton.png

##Singletonパターン必要性
上記で記述したようにインスタンスを一個しか作りたくないときの保証になる
他にも、シングルトンでは遅延実行が重要とされている
理由として静的インスタンスが必要とされない限り、メモリを消費しない
C++の場合では動的初期化の順序が予測できないのでシングルトンを使うことでプログラマがタイミングを自分で決められるという利点もある
一個しか作りたくない以外にも、2個以上できても意味がないものにも使用する

使用例
あるクラスをグローバル変数のように使いたいとき

##関連しているパターン

  • Abstract Factoryパターン
  • Builderパターン
  • Facadeパターン
  • Prototypeパターン

#参考
増補改訂版Java言語で学ぶデザインパターン入門
JavaScriptデザインパターン

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?