4
3

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.

デザインパターン勉強会 第5回:Singletonパターン

Last updated at Posted at 2017-08-30
1 / 13

はじめに

本エントリーは某社内で実施するデザインパターン勉強会向けの資料となります。
本エントリーで書籍「Java言語で学ぶデザインパターン入門」をベースに学習を進めますが、サンプルコードはC#に置き換えて解説します。

第1回:Iteratorパターン
第2回:Adapterパターン
第3回:Template Methodパターン
第4回:Factory Methodパターン


Singletonパターンとは

指定したクラスのインスタンスが1つしか存在しないことを保証するデザインパターンです。  


サンプルプログラムのクラス図

Singletonパターンを使用したサンプルプログラムのクラス図を紹介します。

UML_Singleton.JPG


各クラスの役割

クラス名 役割
Singleton インスタンスが1つしか存在しないクラス
ConfirmSingleton 動作テスト用のクラス

Singletonクラス

Singletonクラスでは、インスタンスは1つしか作られません。
Singletonクラスでは、staticフィールド(クラス変数)として_singletonが定義され、それをSingletonクラスのインスタンスで初期化しています。この初期化はSingletonクラスのロード時に1度だけ行われます。
Singletonクラスのコンストラクタはprivateになっています。
これはSingletonクラス外からコンストラクタを呼び出すことを禁止するためです。
したがって、もし、

new Singleton()  

という式がこのクラス外にあったとしてもコンパイルエラーとなります。

using System;

namespace SingletonSample
{
    public class Singleton
    {
        private static Singleton _singleton = new Singleton();

        private Singleton()
        {
            Console.WriteLine("インスタンスを生成しました。");
        }

        public static Singleton GetInstance()
        {
            return _singleton;
        }
    }
}

ConfirmSingletonクラス

ConfirmSingletonクラスは、Singletonを利用しているクラスです。
ここでは、SingletonクラスのgetInstanceメソッドを使ってSingletonのインスタンスを得ています。
getInstanceメソッドは2回呼び出されています。戻り値はそれぞれobj1とobj2に代入しています。
確かに同じインスタンスが得られているかどうかを、obj1==obj2という式でチェックしています。

using System;

namespace SingletonSample
{
    public class ConfirmSingleton
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Start");
            Singleton obj1 = Singleton.GetInstance();
            Singleton obj2 = Singleton.GetInstance();

            if (obj1 == obj2)
            {
                Console.WriteLine("obj1とobj2は同じインスタンスです。");
            }
            else
            {
                Console.WriteLine("obj1とobj2は同じインスタンスではありません。");
            }

            Console.WriteLine("End");
            Console.ReadLine();
        }
    }
}


実行結果

先のMainを実行した結果は以下の通りです。

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

どんなクラスをSingletonにするケースがあるか

  • キャッシュクラス
    ファイルへのアクセス処理は非常に負荷がかかり、処理速度に影響を及ぼします。
    ファイルの内容の更新は行われないが、参照は頻繁に行われるようなファイルを毎回読み込むのは、効率が良いとは言えません。
    そんなとき、 キャッシュ機構をもつクラスをSingleton化することで、アプリケーションが終了しない限り、キャッシュに保持されたデータをあらゆる局面で取り出すことができるようにできます。

参考URL :
http://www.nulab.co.jp/designPatterns/designPatterns2/designPatterns2-1.html


Singletonは使うべきはないという意見もある

本エントリーでは取り上げませんが、以下のサイトでSingletonパターンを使うべきではない理由がまとめられています。興味のある方はご覧になってみてください。


まとめ

  • Singletonパターンはインスタンスが1つしか存在しないことを保証するデザインパターン
  • インスタンスを得るためのstaticメソッドを用意する
  • クラスの外からnewされないようにコンストラクタをprivateにする

サンプルコード

以下に公開しています。
https://github.com/Keenag/SampleCode


4
3
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
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?