Q&A
自分がインスタンスというものを決まり文句としてしか理解できていないからなのですが、シングルトンの重要性があまりわかりません。
調べてみてもいまいちピンきませんでした、インスタンスがなぜ一つじゃないといけないのか,どのような場面でシングルトンを使うのか、どなたか教えて頂けないでしょうか。
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
下記のような質問は推奨されていません。
- 質問になっていない投稿
- スパムや攻撃的な表現を用いた投稿
適切な質問に修正を依頼しましょう。
回答8件
24
ベストアンサー
インスタンスがなぜ一つじゃないといけないのか
使えるリソースが一つだけの場合、それにアクセスするクラスインスタンスも一つだけの方が都合が良い場合が多いからです。
例えば、画面に何か出力するとき、JavaではSystem.out
を使いますが、それは「標準出力」というたった一つしかないリソースに対してアクセスを行うために、staticフィールドで定義されたインスタンスであり、staticなのでプロセス内には1個しかインスタンスがありません。
なぜそうしているのかというと、画面に何か書きたいときに、いちいちnewしてクラスインスタンスを作るのは面倒だし、そのたびにnewしていたら無駄にメモリを食うし、それを避けるために一度newしたものを別のクラスでも使い回そうとすると、そのインスタンスの受け渡しをどうするのかという問題が出てくるし……。
ということで、staticフィールドにインスタンスを作ってそれをみんなで使い回すことにするのです。
どのような場面でシングルトンを使うのか
シングルトン(パターン)はインスタンスを一つしか作らないことを「保証する」ための仕組みです。
ただ単にインスタンスを一つにしたいというだけならstaticフィールドにすればできますが、それを知らずに誰かがnewしてしまったらインスタンスが複数になってしまいます。あるいは、staticフィールドにインスタンスを作りたいけど、初期化の順番をコントロールしたい、というケースもあるかもしれません。マルチスレッドでの動作を考慮しないといけないかもしれません。
そういうときに一手間かけてシングルトン(パターン)を使います。
投稿2016/06/02 03:24
編集2016/06/02 03:27総合スコア5936
8
例を示します。
1個しかない定義ファイルを読み込んで定義情報を保持するクラス Config を作ったとします。
シングルトン設計でない場合、Config を次のように使います。
Java
1Config c = new Config(); // Config のコンストラクタで定義ファイルを読み込む 2String name = c.getName(); // 定義されている名前を取得
上記の使い方では、new 演算子を実行するたびに、Config のインスタンスが生成されます。
すると、定義ファイルが1個しかないにも関わらず、Config のインスタンスを生成するたびに、定義ファイルを読み込むことになります。
そこで、次のように Config クラスを改善します。
- Config クラスのコンストラクタを public にしないように修正し、
外部プログラムで new 演算子でインスタンスを生成できなくする
0. Config クラスに getInstance() を追加し、
Config 内部で保持しているインスタンスを返す
すると、プログラムでは次のような使い方になります。
Java
1Config c = Config.getInstance(); // 生成済みの Config インスタンスを取得 2String name = c.getName(); // 定義されている名前を取得
この改善により、ただ1つのインスタンスを使いまわすようになります。
そうすれば、定義ファイルを読み込む回数も1回だけになります。
インスタンスを1個しか作らせたくない場合に、シングルトン設計をします。
投稿2016/06/02 02:47
編集2016/06/02 02:49
退会済みユーザー
総合スコア0
下記のような回答は推奨されていません。
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
4
シングルトンを使わないほうがいいケースもあります。
オブジェクトの状態が更新されるようなクラスはシングルトンにしてはいけないです。
他の方の回答にもあるように、リソースが単一で不変なオブジェクトに対してのみシングルトンを検討するべきです。
更新が必要なオブジェクトをシングルトンにしてしまうと、他のスレッドと更新が競合しないようにsyncronizedなどで排他制御を行う必要が出てきて、オーバヘッドが発生します。
ですので、シングルトンは値オブジェクトであるべきです。シングルトンはメモリ効率がよく、アクセシビリティも高いので便利ですが、なんでもかんでもシングルトンは危険ですのでそこだけ注意してください。
投稿2016/06/07 04:38
総合スコア29
下記のような回答は推奨されていません。
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
4
例えば山田さんがいたとします。
山田さんは手帳を持っています。手帳にはスケジュールを記入します。
しかし、山田さんがたくさん手帳を持っていたらどうでしょう。
明日のスケジュールは青色の手帳、
明後日のスケジュールは赤色の手帳、
来週のスケジュールは緑色の手帳と、
バラバラの手帳にメモしたとすると、いざスケジュールを確認するとき、どの手帳を見ていいかわかりません。
しかし、手帳が1冊しかなければ、書き込むのも確認するのも1冊を見ればよいことになります。
シングルトンとはそういうことです。
投稿2016/06/02 02:25
総合スコア9206
下記のような回答は推奨されていません。
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
3
一人ではなく、複数人がプログラミングしていると考えてください。
例えばAさんがA機能、BさんがB機能を作っていたとします。Cさんはそれぞれで使うクラスを定義しています。
A機能とB機能のそれぞれで使うインスタンスをすべてCさんが作ったクラス定義からインスタンス化したとします。
この時にアプリケーション的に1つしか存在しないインスタンス(OS、ファイルアクセスクラスやDBアクセスクラス等)を各自が自由にインスタンス化し変更すると各インスタンス間で不整合が起きないように同期を取る必要が出てきます。
このような不整合が起きないようにするには難度が高く誤りが起こりやすくなります、そこでCさんがシングルトンパターンを適用しアプリケーション内でインスタンスが1つになるように保証します。1つのインスタンスはどこで値が変更されても不整合が起こり得ないので同期も必要ありません。
投稿2016/06/02 03:12
総合スコア18151
下記のような回答は推奨されていません。
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
3
ログ出力などが例になりますかね?
javaなどでは同一ファイルに対するファイル出力のストリームを複数持つことはできません。
だからシステム全体で同一のインスタンスから出力できるようシングルトンで保持する必要が発生するのだと思います。
投稿2016/06/02 02:21
総合スコア5570
下記のような回答は推奨されていません。
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
1
インスタンスがなぜ一つじゃないといけないのか
制限として1つしか持てないオブジェクト(A)があり、複数のオブジェクトから
利用したいとすれば、Aを利用する機能はシングルトンとする必要があります。
tkturboさんの回答はこの例です。
オブジェクトの実装の制限により、1つじゃないとダメになることがあります。
例えばインスタンス生成時に何かの処理を行う人がいて、その処理を一回だけ、
実行して欲しいという場合。
「一回しかしないでね!」とお約束するよりも、機能として一回しか実行されない
ことを保証するのが良いのは言わずもがな。
その実現方法として、シングルトンという選択があります。
sipadan2003さんの回答がこの例です。
どのような場面でシングルトンを使うのか
上記の通り、シングルトンじゃないとダメって時は、当然そうします。
他の方法で回避できる場合もありますが、この辺は設計次第です。
他には、あるオブジェクトをみんなが共有して使いたいという時がたまにあります。
全部の機能にオブジェクトの参照を渡すのが大変。ってとき、シングルトンだと楽です。
Cならグローバル変数を使えば共有できますけど、私はシングルトンの方が好きです。
また、なにかしらの理由でスゴイサイズのメモリをアロケートしなければならない等、
オブジェクトのサイズが非常に大きい場合もシングルトンを選ぶことがあるかと思います。
インスタンスがたくさんできるとメモリを圧迫してしまうからですね。
絶対にシングルトンじゃないとダメ!!というのは、どちらかと言えば稀です。
シングルトンは、デザインパターンの一種で、設計時の選択肢の1つです。
投稿2016/06/02 03:29
総合スコア247
下記のような回答は推奨されていません。
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
0
最近しみじみと必要性を感じたので一言だけ。
データベースを作っていたのですが、AさんからのINSERTはBさんも見れなくてはなりません。
今回作成したのはインメモリDBでしたので、実体がAさん用、Bさん用に出来ては不都合です。
よって単一のリソースを復数人数で参照するにはシングレトンが必須でした。
投稿2016/06/02 03:29
総合スコア208
下記のような回答は推奨されていません。
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
関連した質問
Q&A
解決済
Unity singletonのエラーだと思うのですが解決できません。
回答1
クリップ0
更新
2021/05/18
Q&A
解決済
シングルトンがなぜ必要なのか
回答8
クリップ22
更新
2016/06/02
意見交換
受付中
UnityでのMVPパターンの実装手段について
回答2
クリップ0
更新
2023/03/25
Q&A
解決済
EC2でrbenvをインストールしたい
回答1
クリップ1
更新
2023/03/25
Q&A
解決済
sort()で使うpair型の比較関数をテンプレート化するとエラーが出るので解消したい
回答4
クリップ1
更新
2023/03/12
Q&A
解決済
【Ruby On Rails】配列の中で複数モデルのインスタンスを取得する方法について
回答1
クリップ0
更新
2023/03/16
Q&A
解決済
ssh接続しようとするとkex_exchange_identification: read: Connection reset by peerとエラーになる
回答1
クリップ1
更新
2023/03/28
同じタグがついた質問を見る
Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。
オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
2016/06/02 06:16
2016/06/02 09:37