###前提・実現したいこと
デザインパターンにおけるシングルトンパターンについて
自分の書き方はシングルトンパターンなのか
###発生している問題・エラーメッセージ
自分の書いているコードがシングルトンパターンなのかわかりません。シングルトンを意識して書いていたわけではないのですが、インスタンスを一つしか生成しない点ではシングルトンパターンっぽいけど本質とは全然違う気がします。そもそもオブジェクト指向になっているのかも分かりません。
###該当のソースコード
C++
1//A.h 2class A 3{ 4 //内容A 5}
C++
1//B.h 2class B 3{ 4 //内容B 5}
C++
1//C.h 2class C 3{ 4 //内容C 5}
C++
1#include<iostream> 2#include< A.h > 3#include< B.h > 4#include< C.h > 5 6int main(){ 7 A a;//インスタンス 8 B b;//インスタンス 9 C c;//インスタンス 10 /* 11 処理 12 */ 13 return 0; 14}
###補足情報(言語/FW/ツール等のバージョンなど)
言語はC++。Pythonでも同じような感じで作っています。
シングルトンのように専用のクラスを作ったり、コードとして保証している訳ではありません。それは分かって欲しいです。シングルトンで書かれたコードは見たことがあります。それのコードを回答として貼られても回答になっていないのでご容赦ください。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答10件
0
蛇足コメントで恐縮ですが、みなさんがおっしゃる点と質問者さんの感覚には温度差があるように見えました。
- 自分が設計したコードを自分自身が使い方を分かっていて使うという感覚
- 自分が設計したコードを他者(もしくは時間がたって使い方を忘れてしまっているかも知れない自分)が使っても間違いのない使い方が保証できるという安心感を望む感覚
質問者さんは特定のクラスのインスタンスを一つしか実体化しないコードであることをもってそれを「シングルトン」と呼んでもいいと思っておられます。これは1.の感覚ではないかと思います。
一方、デザインパターンを始めとする様々な方式・パラダイムは「人間は勘違いしたり忘れたりすることで間違いを犯す。プログラマーが少しでも幸せになるためには間違いを排除することが重要であり、方法論にはそのことの配慮が含まれているべき」という思想が大前提として根底に流れています。つまり前述の2.の観点で多くの方法論は議論されるわけです。
自分はクラスA,B,Cが「シングルトンに通じるもの」と考えることはデザインパターンの実例を学んでいく過程においては大事な気づきだと思います。ただ、他者を含めて「シングルトン」という言葉で概念を共有するには一般にシングルトンが備えるべきことは何かを知ることもまた大事と思います。両方を通じて多くの人と齟齬なくコミュニケーションが取れるようになっていくと思います。
投稿2017/04/23 06:15
総合スコア18404
0
いいえ、シングルトンパターンではありません。
シングルトンパターンとは、シングルトンとして定義されたクラスについて、「インスタンスを一つしか作らない」ではなく、「インスタンスを一つしか作れない」ようにするデザインパターンです。つまり、二つ目のインスタンスの生成が原則不可能にすることで、そのクラスのインスタンスが全て同一であることを保証するのが目的です。保証が無ければシングルトンパターンではありません。
クラスをシングルトンにする方法ですが、言語によって様々です。C++では全てのコンストラクタをprivateにして、常に同じインスタンスを返すstaticなメンバー関数経由でしかインスタンスを作れない(取得できない)ようにします。Pythonでは__new__
を上書きして、常に同じインスタンスが生成されるようにします。他にも、モジュールをMix-inする(Ruby)とか、シングルトンになるオブジェクトを直接定義する(Scala)とか、様々です。同じ言語であってもスレッドセーフにするかしないかでも書き方が変わってきます。
投稿2017/04/22 21:24
総合スコア21751
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
ベストアンサー
回答者からは実際のコードが確認できませんが、例えばclassAを実際に複数生成すると動作が成り立たず、それをあなた自身が分かっていて、それを理解したうえでmain関数を書いているならば、classAはシングルトンパターンであるべきクラスであるとは言えると思います。
ただし現状ではシングルトンパターンであるとは言えません。やろうと思えば複数生成できてしまうからです。
シングルトンパターンとは、複数生成されると困るクラスについて、クラス側で複数生成されようとした時にも不具合を起こさないように制御することがパターンの狙いの本質だと理解してください。
認識の違いの一点として、シングルトンパターンは提示のコードのmain関数に対して合致するものではなく、classA~Cのようなクラス定義に対して合致するものであるという認識が弱いのではないかと予想します。
main関数で一つしか作らないからといってそれはシングルトンパターンとは全く関係がなく、classA~Cのコーディングとして複数生成時の制御をかけるということがシングルトンパターンです。
投稿2017/04/23 00:24
編集2017/04/23 00:29総合スコア1947
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
シングルトン自体は概ねアンチパターンと化しています… ということを誰かに書いといて欲しかったなぁ… と思うのでクローズされていますが追記です。
なお、これはVictoriqueさんのコードがシングルトンというのではありません。
まず初めに、シングルトンパターンはさておき、シングルトン自体は「1個しか作らない」とか「作れない」ということではありません。
ただこれは「シングルトン」の定義が今現在明確になっているというわけではありません。 経験的にシングルトンな性質が他のオブジェクトに伝播するため暗黙的共通認識…みたいなものです。 シングルトンというのは言葉の定義から曖昧です。 シングルと比べると、特定的な個人である(ファミリーではない)、というような意味です。
もしもclass A, B, Cを何度インスタンス化しても、全てのABCで同一の情報を共有できるならそれはシングルトンと同一の特性を持ちます。シングルトンパターンは使っていませんが、それでもほぼシングルトンと言っていいでしょう。
これはシングルトンパターンを使ったオブジェクトと蜜結合する他のオブジェクトに実際に頻繁に起こる問題です。
シングルトンと結合したクラスは実質シングルトンになります。
シングルトンがオブジェクトの依存関係の不鮮明化、蜜結合を引き起こします。
シングルトンとロジックを結合させる行為は明確にアンチパターンです。
それではグローバル変数の乱用と変わりありません。
安易なシングルトンパターンの適用は忌避されます。
シングルトンパターンを使うのが最適な状況というのからして本来少ないのです。
使う場合もインターフェースを使い、コンストラクタインジェクション等で直接的な結合を避けるように指導することが多いです。
シングルトンパターンは古く、選択的なシングルと付き合うことを目的としたより進化したデザインパターンが登場しています。 > Dependency Injection パターン
シングルトンパターンが解決したかったことも、シングルトンにすることではありません。
何故アンチパターンになるのか、具体的に書くと長くなりすぎるため、警鐘のみに留めておきます。
投稿2017/04/26 02:45
編集2017/04/26 02:55総合スコア1593
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/04/28 03:05

0
こんにちは。
シングルトンの特徴は、他の方もおっしゃっているようにインスタンスを1つしか作れないことが最大ですが、もう一つあります。その唯一のインスタンスにグローバルにアクセスできることです。
密な関係にあるクラスや関数には、インスタンスを引数等で次々と渡すことが多いので、その間で1つのインスタンスを共有することは良く行われます。
その場合にまでシングルトンを使うかというと、わざわざそのようにしない人が大半と思います。インスタンスを1つしか作れないということは汎用性が劣化しています。必要もないのに、使いにくくするのは愚かですから。
逆に、関連性の低いクラスや関数でも、同じインスタンスを使いたい場合があります。Zuishinさんが例に出されている「設定」や、ロガーなどもその1つでしょう。
そのような関連性の低いクラスにも、そのインスタンスをバラメータで引き渡すのは却って可読性を下げるし、メンテナンス性も劣化します。素直にグローバル変数にするべきでしょう。
この場合、きちんとドキュメントに使用するべきグローバル変数を記述し、かつ、ローカルに生成するなと書いておく必要があり、かつ、プログラマはその記述をきちんと読み、覚えるか、必要に応じてドキュメントを確認する必要があります。
作業が増えるので生産性は劣化します。更に、もし書き損なったり読み損なったりして、ローカルに生成するとバグを生み、大きく生産性を落とします。
その時、ローカルにインスタンスを作れなくしてそのようなミスを防ぐ効果があるのがシングルトンです。デバッグする時、そのような間違いを疑わないで済むのでたいへんありがたいです。
投稿2017/04/23 03:47
総合スコア23274
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
例えばアプリケーションの設定ファイルを読み書きするクラスを作ったとします。
このクラスはインスタンス生成時に設定ファイルを読み込み、Save() が呼ばれた時点でユーザーによる設定の変更を元のファイルに保存します。
このクラスをアプリケーション実行時に生成して設定を読み込み、終了時に保存します。
後日、設定の一部について任意の場所で読み書きする必要が生まれました。
そこであなたはこのクラスを生成し、変更を保存する事に決めました。
アプリケーションの起動時と終了時、任意の時と場所、ソース中ではこの二カ所でこのクラスが使われています。
そうすると、任意の場所で保存した設定は、アプリケーション終了時に上書きされてしまいます。
あなたは、なぜ変更した設定が保存されないのか悩み、数時間をバグ取りに費やしました。
シングルトンはこのような時に使います。何度インスタンスを取得してもそれは最初の物と同じものなので競合が起こりません。
シングルトンはインスタンスを一つしか作らないデザインではなく、いつでも同じインスタンスを返すデザインです。
投稿2017/04/22 22:00
総合スコア28673
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
自分の書き方はシングルトンパターンなのか
シングルトンパターンではありません。
あなたが実装したクラスAがあるとして、それを利用する側(この場合は main関数)が絶対にインスタンスをひとつしか作ることができない場合に、クラスAはシングルトンパターンで実装されていると言えます。
今の状況は、たまたまインスタンスをひとつ作っているだけです。
投稿2017/04/22 21:12
総合スコア938
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
「世界に一つだけのインスタンス」がシングルトンであるなら、
僕は「世界に一つだけ」であることをコードで保証します。たとえば:
C++
1class Singleton { 2private: 3 Singleton(); // privateなのでSingleton以外誰も作れない 4 ~Singleton(); 5public: 6 static Singleton* instance(); 7}; 8 9Singleton* Singleton::instance() { 10 // 何度呼ばれても同じものを返す 11 static Singleton only_one; 12 return &only_one; 13} 14 15int main() { 16 Singleton* obj = Singleton::instance(); 17 sub(): 18 ... 19} 20 21void sub() { 22 Singleton* obj = Singleton::instance(); 23 // objは唯一のインスタンスなので引数で引き渡す必要も 24 // グローバル変数である必要もない 25}
投稿2017/04/22 21:05
総合スコア16612
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
- 逆引きカタログ Singleton
http://www.nulab.co.jp/designPatterns/designPatterns2/designPatterns2-1.html
...
シングルトンパターンの特徴は、シングルトンクラスのオブジェクト生成を、シングルトンクラス自身が提供するオブジェクト生成用メソッドで行うことです
...
質問文にあるコードは、シングルトンパターンではありません。
呼び出されるクラス側でインスタンスが1つになるような仕組みを用意するのが、シングルトンパターンです。
呼び出す側がどのようにインスタンス生成をしているかは関係ありません。
質問文のコードは、インスタンス生成をクラスごとに1度だけ呼んでいるというだけです。
投稿2017/04/22 23:45
総合スコア22328
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
シングルトンとは、プログラムの文法レベルでインスタンスを一つのみに制限するものです。ローカルルールを作ることでインスタンスを一つのみに制限してもシングルトンとは言いません。
投稿2017/04/23 03:20
総合スコア4853
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。