質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • Python

    11762questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • C++

    4436questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • オブジェクト指向

    328questions

    オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

  • デザイン

    96questions

    プログラミングでのデザインとは、プログラムの構成や、使用の信頼性・持続性・正確性・利便性の目標達成にはどうするのがベストなのか特定の選択を行うことです。

  • デザインパターン

    80questions

    デザインパターンは、ソフトウェアのデザインでよく起きる問題に対して、解決策をノウハウとして蓄積し再利用出来るようにした設計パターンを指します。

デザインパターンシングルトン、オブジェクト指向について

解決済

回答 10

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 4,032

_Victorique__

score 1167

前提・実現したいこと

デザインパターンにおけるシングルトンパターンについて
自分の書き方はシングルトンパターンなのか

発生している問題・エラーメッセージ

自分の書いているコードがシングルトンパターンなのかわかりません。シングルトンを意識して書いていたわけではないのですが、インスタンスを一つしか生成しない点ではシングルトンパターンっぽいけど本質とは全然違う気がします。そもそもオブジェクト指向になっているのかも分かりません。

該当のソースコード

//A.h
class A
{
    //内容A
}
//B.h
class B
{
    //内容B
}
//C.h
class C
{
    //内容C
}
#include<iostream>
#include< A.h >
#include< B.h >
#include< C.h >

int main(){
    A a;//インスタンス
    B b;//インスタンス
    C c;//インスタンス
    /*
            処理
      */
    return 0;
}

補足情報(言語/FW/ツール等のバージョンなど)

言語はC++。Pythonでも同じような感じで作っています。
シングルトンのように専用のクラスを作ったり、コードとして保証している訳ではありません。それは分かって欲しいです。シングルトンで書かれたコードは見たことがあります。それのコードを回答として貼られても回答になっていないのでご容赦ください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 10

+11

蛇足コメントで恐縮ですが、みなさんがおっしゃる点と質問者さんの感覚には温度差があるように見えました。

  1. 自分が設計したコードを自分自身が使い方を分かっていて使うという感覚
  2. 自分が設計したコードを他者(もしくは時間がたって使い方を忘れてしまっているかも知れない自分)が使っても間違いのない使い方が保証できるという安心感を望む感覚

質問者さんは特定のクラスのインスタンスを一つしか実体化しないコードであることをもってそれを「シングルトン」と呼んでもいいと思っておられます。これは1.の感覚ではないかと思います。

一方、デザインパターンを始めとする様々な方式・パラダイムは「人間は勘違いしたり忘れたりすることで間違いを犯す。プログラマーが少しでも幸せになるためには間違いを排除することが重要であり、方法論にはそのことの配慮が含まれているべき」という思想が大前提として根底に流れています。つまり前述の2.の観点で多くの方法論は議論されるわけです。

自分はクラスA,B,Cが「シングルトンに通じるもの」と考えることはデザインパターンの実例を学んでいく過程においては大事な気づきだと思います。ただ、他者を含めて「シングルトン」という言葉で概念を共有するには一般にシングルトンが備えるべきことは何かを知ることもまた大事と思います。両方を通じて多くの人と齟齬なくコミュニケーションが取れるようになっていくと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+9

いいえ、シングルトンパターンではありません。

シングルトンパターンとは、シングルトンとして定義されたクラスについて、「インスタンスを一つしか作らない」ではなく、「インスタンスを一つしか作ない」ようにするデザインパターンです。つまり、二つ目のインスタンスの生成が原則不可能にすることで、そのクラスのインスタンスが全て同一であることを保証するのが目的です。保証が無ければシングルトンパターンではありません。

クラスをシングルトンにする方法ですが、言語によって様々です。C++では全てのコンストラクタをprivateにして、常に同じインスタンスを返すstaticなメンバー関数経由でしかインスタンスを作れない(取得できない)ようにします。Pythonでは__new__を上書きして、常に同じインスタンスが生成されるようにします。他にも、モジュールをMix-inする(Ruby)とか、シングルトンになるオブジェクトを直接定義する(Scala)とか、様々です。同じ言語であってもスレッドセーフにするかしないかでも書き方が変わってきます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/23 06:31

    保証するのが目的なのは分かっています。
    聞きたいのはそういうことではなくて、そういう保証がされた状態で書けるプログラムを書いた場合には上記のような感じになるのか、という意味です。また、それがそもそもオブジェクト指向として正しいのかということです。
    素人なので変な質問ですが申し訳ないです。

    キャンセル

  • 2017/04/23 06:42

    C++でシングルトンパターンを実装する場合、コンストラクタをprivateにする必要があるため、クラス内部以外からコンストラクタを直接呼び出せるような書き方にはなりえません。つまり、`A a;`のようなインスタンス生成がクラス外にある書き方にはなりません。

    ただ、これはC++に言えることで、他の言語では異なります。Pythonはオブジェクト生成(__new__)自体を上書きできるため、通常のインスタンス生成と同じ書き方をクラス外で使ってもシングルトンにすることができます。

    キャンセル

checkベストアンサー

+6

回答者からは実際のコードが確認できませんが、例えばclassAを実際に複数生成すると動作が成り立たず、それをあなた自身が分かっていて、それを理解したうえでmain関数を書いているならば、classAはシングルトンパターンであるべきクラスであるとは言えると思います。

ただし現状ではシングルトンパターンであるとは言えません。やろうと思えば複数生成できてしまうからです。
シングルトンパターンとは、複数生成されると困るクラスについて、クラス側で複数生成されようとした時にも不具合を起こさないように制御することがパターンの狙いの本質だと理解してください。

認識の違いの一点として、シングルトンパターンは提示のコードのmain関数に対して合致するものではなく、classA~Cのようなクラス定義に対して合致するものであるという認識が弱いのではないかと予想します。
main関数で一つしか作らないからといってそれはシングルトンパターンとは全く関係がなく、classA~Cのコーディングとして複数生成時の制御をかけるということがシングルトンパターンです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+4

「世界に一つだけのインスタンス」がシングルトンであるなら、
僕は「世界に一つだけ」であることをコードで保証します。たとえば:

class Singleton {
private:
  Singleton(); // privateなのでSingleton以外誰も作れない
  ~Singleton();
public:
  static Singleton* instance();
};

Singleton* Singleton::instance() {
  // 何度呼ばれても同じものを返す
  static Singleton only_one;
  return &only_one;
}

int main() {
  Singleton* obj = Singleton::instance();
  sub():
  ...
}

void sub() {
  Singleton* obj = Singleton::instance();
  // objは唯一のインスタンスなので引数で引き渡す必要も
  // グローバル変数である必要もない
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+4

自分の書き方はシングルトンパターンなのか

シングルトンパターンではありません。

あなたが実装したクラスAがあるとして、それを利用する側(この場合は main関数)が絶対にインスタンスをひとつしか作ることができない場合に、クラスAはシングルトンパターンで実装されていると言えます。

今の状況は、たまたまインスタンスをひとつ作っているだけです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/23 06:14

    捕捉にも書きましたが、一つしか作らなくて済むような書き方をしているという点ではシングルトンと同じと言えますか?

    キャンセル

  • 2017/04/23 06:21

    私には「一つしか作らなくて済むような書き方」がされているようには見えません。

    すべてのコードを自分ひとりで作成している場合、クラスが「一つしか作らなくて済むように実装されている」ことと、「今作成したプログラムではクラスAのインスタンスは一つだけである」ことの差がわかり辛いかもしれません。

    あなたが実装したクラスAを私が利用するとして、私がどのように頑張ってもクラスAのインスタンスをひとつしか作成できない場合に初めて「クラスAがシングルトンパターンで実装されている」と言えます。

    キャンセル

  • 2017/04/23 06:28

    では、私がそういう意図で作ったとして、それはシングルトンの意図と変わりないということでよろしいのですか?
    他人が使う場合には2つ以上作れてしまいますが
    本質という意味ではそういうことで良いのですか?
    私は素人ですのですごく変な質問かもしれません、ごめんなさい

    キャンセル

  • 2017/04/23 07:12

    あなたが「クラスAのインスタンスは一つしか作らない」と考えていたとして、それがコードとして(クラスAの実装として)表現できていなければいけません。

    現実世界にはドキュメントに「このクラスは複数のインスタンスを作成した場合、正常に動作しません」と公言し、利用者側に注意深くコードを書くことを強要するライブラリも存在しています。あまつさえ、ドキュメントにすら記載されていないものもあります。

    将来そのようなライブラリに遭遇した時にシングルトンパターンの必要性を知るでしょう。

    キャンセル

+4

例えばアプリケーションの設定ファイルを読み書きするクラスを作ったとします。
このクラスはインスタンス生成時に設定ファイルを読み込み、Save() が呼ばれた時点でユーザーによる設定の変更を元のファイルに保存します。

このクラスをアプリケーション実行時に生成して設定を読み込み、終了時に保存します。

後日、設定の一部について任意の場所で読み書きする必要が生まれました。
そこであなたはこのクラスを生成し、変更を保存する事に決めました。

アプリケーションの起動時と終了時、任意の時と場所、ソース中ではこの二カ所でこのクラスが使われています。

そうすると、任意の場所で保存した設定は、アプリケーション終了時に上書きされてしまいます。
あなたは、なぜ変更した設定が保存されないのか悩み、数時間をバグ取りに費やしました。

シングルトンはこのような時に使います。何度インスタンスを取得してもそれは最初の物と同じものなので競合が起こりません。
シングルトンはインスタンスを一つしか作らないデザインではなく、いつでも同じインスタンスを返すデザインです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+4

こんにちは。

シングルトンの特徴は、他の方もおっしゃっているようにインスタンスを1つしか作れないことが最大ですが、もう一つあります。その唯一のインスタンスにグローバルにアクセスできることです。

密な関係にあるクラスや関数には、インスタンスを引数等で次々と渡すことが多いので、その間で1つのインスタンスを共有することは良く行われます。
その場合にまでシングルトンを使うかというと、わざわざそのようにしない人が大半と思います。インスタンスを1つしか作れないということは汎用性が劣化しています。必要もないのに、使いにくくするのは愚かですから。

逆に、関連性の低いクラスや関数でも、同じインスタンスを使いたい場合があります。Zuishinさんが例に出されている「設定」や、ロガーなどもその1つでしょう。
そのような関連性の低いクラスにも、そのインスタンスをバラメータで引き渡すのは却って可読性を下げるし、メンテナンス性も劣化します。素直にグローバル変数にするべきでしょう。

この場合、きちんとドキュメントに使用するべきグローバル変数を記述し、かつ、ローカルに生成するなと書いておく必要があり、かつ、プログラマはその記述をきちんと読み、覚えるか、必要に応じてドキュメントを確認する必要があります。
作業が増えるので生産性は劣化します。更に、もし書き損なったり読み損なったりして、ローカルに生成するとバグを生み、大きく生産性を落とします。

その時、ローカルにインスタンスを作れなくしてそのようなミスを防ぐ効果があるのがシングルトンです。デバッグする時、そのような間違いを疑わないで済むのでたいへんありがたいです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+4

シングルトン自体は概ねアンチパターンと化しています… ということを誰かに書いといて欲しかったなぁ… と思うのでクローズされていますが追記です。
なお、これはVictoriqueさんのコードがシングルトンというのではありません。


まず初めに、シングルトンパターンはさておき、シングルトン自体は「1個しか作らない」とか「作れない」ということではありません。

ただこれは「シングルトン」の定義が今現在明確になっているというわけではありません。
経験的にシングルトンな性質が他のオブジェクトに伝播するため暗黙的共通認識…みたいなものです。

シングルトンというのは言葉の定義から曖昧です。
シングルと比べると、特定的な個人である(ファミリーではない)、というような意味です。

もしもclass A, B, Cを何度インスタンス化しても、全てのABCで同一の情報を共有できるならそれはシングルトンと同一の特性を持ちます。シングルトンパターンは使っていませんが、それでもほぼシングルトンと言っていいでしょう。
これはシングルトンパターンを使ったオブジェクトと蜜結合する他のオブジェクトに実際に頻繁に起こる問題です。
シングルトンと結合したクラスは実質シングルトンになります。

シングルトンがオブジェクトの依存関係の不鮮明化、蜜結合を引き起こします。
シングルトンとロジックを結合させる行為は明確にアンチパターンです。
それではグローバル変数の乱用と変わりありません。
安易なシングルトンパターンの適用は忌避されます。

シングルトンパターンを使うのが最適な状況というのからして本来少ないのです。
使う場合もインターフェースを使い、コンストラクタインジェクション等で直接的な結合を避けるように指導することが多いです。
シングルトンパターンは古く、選択的なシングルと付き合うことを目的としたより進化したデザインパターンが登場しています。 > Dependency Injection パターン

シングルトンパターンが解決したかったことも、シングルトンにすることではありません。

何故アンチパターンになるのか、具体的に書くと長くなりすぎるため、警鐘のみに留めておきます。

> シングルトンパターン アンチパターン

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/27 19:25

    ありがとうございます!デザインパターンについては無知なので勉強中です。参考にさせていただきます。

    キャンセル

  • 2017/04/28 12:05

    「シングルトン自体は概ねアンチパターン」と聞いて。

    『Singletonパターンはどのようなときに使うのか?』
    http://qiita.com/ndxbn/items/c7a37ea950876176bb81

    キャンセル

  • 2017/04/28 13:21 編集

    もうちょっと簡単にすると
    ・フレームワーク的なコード(ドメインロジックに関係の無いコード)
    ならOKと考えています。

    フレームワーク的な、とは大体は、それ自体が他のコードとのバスの役割を果たすコードです。

    AbstractFactory/Builderパターンはそうです。

    その最たるものがロガーですし、グローバルな設定口を持ったフレームワークは結構あります。
    ドメインロジックとしてシングルトンを使う時は、(より良い方法があるから)ありません。

    Propertyパターンは、String.Emptyみたいなものですかね。
    ある状態としてのオブジェクトを使いまわすためのシングルトンというのはありますね。
    あえてシングルトンにする必要はないですが、イミュータブルクラスのメンバにstaticなDefaultインスタンスを付加するというのはよくやりますね。

    キャンセル

+3

...
シングルトンパターンの特徴は、シングルトンクラスのオブジェクト生成を、シングルトンクラス自身が提供するオブジェクト生成用メソッドで行うことです
...

質問文にあるコードは、シングルトンパターンではありません。

呼び出されるクラス側でインスタンスが1つになるような仕組みを用意するのが、シングルトンパターンです。
呼び出す側がどのようにインスタンス生成をしているかは関係ありません。

質問文のコードは、インスタンス生成をクラスごとに1度だけ呼んでいるというだけです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

シングルトンとは、プログラムの文法レベルでインスタンスを一つのみに制限するものです。ローカルルールを作ることでインスタンスを一つのみに制限してもシングルトンとは言いません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • Python

    11762questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • C++

    4436questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • オブジェクト指向

    328questions

    オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

  • デザイン

    96questions

    プログラミングでのデザインとは、プログラムの構成や、使用の信頼性・持続性・正確性・利便性の目標達成にはどうするのがベストなのか特定の選択を行うことです。

  • デザインパターン

    80questions

    デザインパターンは、ソフトウェアのデザインでよく起きる問題に対して、解決策をノウハウとして蓄積し再利用出来るようにした設計パターンを指します。