【Gang of Four】デザインパターン学習 - Singleton


Singleton - 1枚札

目次
生成に関するパターンの最後はシングルトンです。これは誰にとっても馴染みのあるパターンかと思います。自分も一番最初に知ったデザインパターンはシングルトンだったような気がする。

DB接続を提供するクラスやアセットを取得するようなクラスは大体このパターンで実装されていますね。プログラム中で当該クラスのインスタンスの唯一性を保証します。

目的

あるクラスに対してインスタンスが1つしか存在しないことを保証し、それにアクセスするためのグローバルな方法を提供する。

構成要素

・Singleton インスタンスが1つしか生成されないクラス

実装

本パターンはkotlinでコーディングすると下記のように鬼シンプルな形になってしまいよくわからないため、javaでコーディングします。

SingletonObject.kt
package singleton

object SingletonObject {
    var str = ""

    fun print() {
        println("出力結果:$str")
    }
}

複数の画面からシングルトンオブジェクトを介して画像や音楽ファイルを作成します。

Singleton インスタンスが1つしか生成されないクラス

シングルトンオブジェクト

JavaSingletonObject.java
package singleton;

public class JavaSingletonObject {
    /**
     * staticで定義し自クラスのインスタンスを唯一とする
     */
    public static JavaSingletonObject instance = new JavaSingletonObject();
    private String address = "/assets/temp";
    enum Assets {
        IMAGE1("image_1"),
        IMAGE2("image_2"),
        AUDIO1("audio_1"),
        AUDIO2("audio_2");

        private final String value;

        Assets(final String value) {
            this.value = value;
        }
    }

    /**
     * コンストラクタをprivateで定義し、新たなインスタンスを生成できないようにする。
     */
    private JavaSingletonObject(){
        System.out.println("接続:" + address);
    }

    public String getAssets(Assets target) {
        System.out.println("シングルトンオブジェクトで資材取得:" + target.value);
        return target.value;
    }
}

画面1クラス

DisplayOne.kt
package singleton

class DisplayOne {
    fun draw() {
        println("User1で${JavaSingletonObject.instance.getAssets(JavaSingletonObject.Assets.IMAGE1)}を描画!!")
    }
}

画面2クラス

DisplayTwo.kt
package singleton

class DisplayTwo {
    fun start() {
        println("User2で${JavaSingletonObject.instance.getAssets(JavaSingletonObject.Assets.AUDIO1)}を再生!!")
    }
}

使用者

画面管理クラス

Manager.kt
package singleton

class Manager {
    init {
        DisplayOne().draw()
        DisplayTwo().start()
    }
}

以上でシングルトンパターンの実装が完了しました。JavaSingletonObjectクラスのコンストラクタでassetsへの接続を確立しているため、本処理は1回のみ実行されることになっています。

またコンストラクタをprivateで定義しているため当該クラスのインスタンスを新たに生成することができなくなり唯一性が保証されます。

出力結果

[output]
接続:/assets/temp
シングルトンオブジェクトで資材取得:image_1
User1でimage_1を描画!!
シングルトンオブジェクトで資材取得:audio_1
User2でaudio_1を再生!!