0
2

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 1 year has passed since last update.

デザインパターン_Singleton

Posted at

Singletonパターンとは

クラスでインスタンスが1つしかなく,どこからでも値を持ったインスタンスを
取得することができるパターン

参照

Singleton何が悪いの?
【Singeltonパターン】考え方は単純だが、使いどころが大切なデザインパターン【コード例はRubyとJava】
シングルトンが邪悪な理由
シングルトンパターンの誘惑に負けない

クラス図

300px-Singleton_UML_class_diagram.svg.png
wiki-Singletonパターンより引用

メリット

メリット

  • メモリを節約できる

メモリを節約できる

インスタンスを,生成するとヒープ領域にインスタンス分のメモリが,割り当てられる.
それが,Singletonパターンの場合1回で済むのでメモリの節約になる

デメリット

  • グローバル変数化する
  • 状態を持ち続ける
  • ユニットテストがしにくい

グローバル変数化する

インスタンスが1個で固定されていて,それが常に保有されている
そして,どこからでも変更ができるので,エラーの原因になったり,コードの複雑性に繋がったりする

状態を持ち続ける

グローバル変数と一緒なのだが,状態を持ち続けてしまうことで
どこかで,値を変えられた時に原因を突き止めるのが難しくなる.

ユニットテストがしにくい

理論的には独立しているはずのコード間に暗黙の依存関係を生んでしまう。これが問題なのは、まず依存関係が一見してわかりにくいからです。また、生まれてしまう依存関係は、本来不必要なはずです。問題の存在がはっきりするのは、ユニットテストの時です。ユニットテストは疎結合が前提となっていて、また「本物の」実装コードの代わりに、適宜モック(テスト用の偽者)実装に差し替えられることも重要だ、からです。シングルトンパターンはその妨げになるのです。

シングルトンパターンの誘惑に負けないより引用

処理

Singleton

Singleton.h
template <class T>
class Singleton
{
public:
    static T& GetInstance(){
        static T instance;
        return instance;
    }
protected:
    Singleton() {};
    virtual ~Singleton() {};
};

Test

Test.h
#include<string>
#include"Singleton.h"

using namespace std;

class TEST1 :public Singleton<TEST1>
{
    friend Singleton<TEST1>;
private:
    TEST1() {};
    ~TEST1() {};
public:
    void SetStr(const string str) { this->str = str; }
    string GetStr()const { return str; }
private:
    std::string str;
};


class TEST2 :public Singleton<TEST2>
{
    friend Singleton<TEST2>;
private:
    TEST2() {};
    ~TEST2() {};
public:
    void SetStr(const string str) { this->str = str; }
    string GetStr()const { return str; }
private:
    std::string str;
};

Main

main.cpp
#include <iostream>
#include "Test.h"

using namespace std;

int main()
{
    TEST1& test1 = TEST1::GetInstance();
    test1.SetStr("test1");
    //output: test1
    cout << test1.GetStr() << endl;


    TEST2& test2 = TEST2::GetInstance();
    test2.SetStr("test2");
    //output: test2
    cout << test2.GetStr() << endl;

    return 0;
}

実行結果

実行結果
test1
test2
0
2
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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?