• ベストアンサー

singletonパターン

デザインパターンを勉強しているのですが、一つ気になっていることがあります。singletonパターンを使うとき、staticなメソッドgetInstance();で、唯一のインスタンスを得る場合、コードは Singleton obj1 = Singleton.getInstance(); となります。ここで疑問に思ったんですが、あるメソッドを使う場合、 instance名.method();という具合に記述されるんですが、この場合、 class名.method();となっています。メソッドを使うときって、class名.method();でも大丈夫なんですか?質問文がわかりにくいかもしれませんがどうぞよろしくお願いします。

  • Java
  • 回答数4
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

通常はクラス自身は作業領域にないので操作(メソッドの使用)できません。操作する場合はその複製(オブジェクト)を作業領域に作成して、操作します。ただし、Static(静的)なメソッドは動的なメンバーと違い、作業領域を決め打ち(静的に)で確保します。よって、直接使用できます。 ちょっと説明に御幣があるところがありますがイメージ的にこんな感じです。私の説明に分かり難いところがありましたら、補足をお願いいたします。

serasa
質問者

補足

ありがとうございます。メソッドがstaticだからできるのでしょうか?それともclassがstaticだからでしょうか?この部分だけもう一度お願いします。すみません。。

その他の回答 (3)

回答No.4

staticというのは、そのクラス自体の属性(グローバル変数)やふるまい(メソッド)ですよ、というのを示す修飾子です。 クラスとインスタンスはよくクッキー型とクッキーに例えられると思うのですが、クッキー型がハートの形をしているというような情報はstaticです。その型で作られたクッキー(インスタンス)はすべてハート型ですね。 singletonに話をもどしますと、そのクッキー型はたった1つだけしかクッキーを作りません。誰かが勝手に新しいクッキーを作ろうとしてもできないようにしています(コンストラクタをpriveteにしているはずです)。クッキーを手に入れたいと思ったら、そのクッキー型に「クッキーをちょうだい」と頼むしかありません。それがgetInstanceメソッドです。 No.3さんがおっしゃているように、singletonになるかどうかはgetInstanceメソッドの中の実装次第です。「クッキーちょうだい」と言われたときに、まだ1つも作っていなければ、作ってそれを返します。すでに作ったことがある場合は、その前に作ったものを返します。前の人がもらったクッキーと、新しくもらったクッキーはまったく同じものです(クッキーだとイメージしにくいですね…)。 つまり、インスタンスをやり取りするとき、インスタンスそのものを渡すのではなく、そのインスタンスが存在している場所を渡しているのです。singletonでは、常に同じ場所(同じインスタンス)を返しているのです。 例えが下手ですみません。なんとなくわかっていただけたでしょうか。

回答No.3

ちょっと勘違いをしているかな?クラスのインスタンスとしてオブジェクトを生成するのです。インスタンスにはStaticという概念がありません。Staticになるのはオブジェクト変数です。たぶんですが、 Singleton obj1 = Singleton.getInstance(); このステップを勘違いしている(特にgetInstanceの部分)のだと思いますので、ちょっと説明します。 クラスのインスタンスを生成する場合は、以下のように書きます。 Singleton obj1 = new Singleton(); これはSingletonクラス型のオブジェクト変数obj1を宣言し(左辺)、Singletonクラスのインスタンスを作成し(右辺)、代入しています。 Singleton obj1 = Singleton.getInstance();はgetInstanceメソッドがSingletonオブジェクトを戻り値としているだけです。インスタンスを生成しているかどうかはgetInstanceメソッドの中身次第です。なんだか説明が微妙になってしまい申し訳ない。一度、Javaの仕様、構文の基礎を調べてみてはいかがでしょうか?

serasa
質問者

お礼

お礼を書くのが遅くなって申し訳ありませんでした。はい、もう一度調べてみます。どうもありがとうございました!!

回答No.2

#1です。補足の返信です。 メソッドがstaticだからです。クラス自体はStaticにできません。(ぶっきらぼうな回答になってしまいましたがご了承ください。)

serasa
質問者

補足

すみません、間違えました!インスタンスがstaticだからですか?たびたび申し訳ありません。いつでもいいのでどうかお願いしますm(__)m

関連するQ&A

  • Singletonの使い方

    Singletonはインスタンスを一つしか作らせないデザインパターンと聞いたのですが、インスタンスを一つしか作らせない場合とはどういう場合なのでしょうか?良い具体例とかありましたら教えてください。

  • CakePHPでシングルトンパターン

    CakePHPでシングルトンパターンで、インスタンスを使いまわしたいのですが、 うまく動作しません。 以下のようなプログラムですが、何か設定が足りないのでしょうか class Test{   public static $instance = null;   public function __construct(){}   public function getInstance(){    if(is_null(Test::$instance)){     Test::$instance = new Test();    }    return Test::$instance;   } } 上記クラスを以下のように呼び出しております。 $instance = Test::getInstance(); 何度やっても、インスタンスが新しく生成されてしまします。 良い方法がございましたら、ご教授下さい。

    • ベストアンサー
    • PHP
  • C++ シングルトン マルチスレッド

    標準C++でシングルトンを実装したいのですが。 class Singleton{ public: static Singleton* getInstance(){ if (_instance == NULL){ //スレッドAがこの時点で、スレッドBがNULLチェックすると破綻する _instance = new Singleton(); } return _instance; } private: Singleton(); static Singleton* _instance; }; マルチスレッドになると上記のパターンで破綻するといわれどうしたものかと考えております。 static Singleton* _instance = new Singleton(); と出来れば解決なのですが 「static const int データメンバ以外をクラス内で初期化することはできません」 とのことでそれもできず。 どのようにすればよいでしょうか。

  • singletonの使い方

    はじめまして。 singleton(GoF)で少し疑問に思ったところがありましたので、 アドバイスをいただけたらと思い質問させていただきます。 たとえば以下のようなプログラムですが、 ==form.html== <html> <body> <form action="./Main.php" method="post"> name:<br /> <input type="text" size="20" name="name" /><br /> text:<br /> <textarea rows="8" cols="40" name="text"></textarea><br /> <br /> <input type="submit" value="submit!" /> <input type="reset" value="reset!" /> </form> </body> </html> ==Main.php== <?php require_once "Data.php"; require_once "NullCheck.php"; $data =& Data::getInstance(); $data->setName($_POST["name"]); $data->setText($_POST["text"]); $nc = new NullCheck($data); $result = $nc->check(); if(!$result == ""){ echo $result; }else{ echo "ok"; } ?> ==Data.php== <?php class Data{ var $name; var $text; function &getInstance(){ static $instance; if(!isset($instance)){ $instance = new Data(); } return $instance; } function setName($name){ $this->name = $name; } function setText($text){ $this->text = $text; } function getName(){ return $this->name; } function getText(){ return $this->text; } } ?> ==NullCheck.php== <?php class NullCheck{ var $data; var $err = ""; function NullCheck($data){ $this->data = $data; } function check(){ if($this->data->getName() == ""){ $err .= "nameが空欄です。<br>"; } if($this->data->getText() == ""){ $err .= "textが空欄です。<br>"; } return $err; } } ?> 上記を作る際、 submitを押すたびにオブジェクトが作られるのは無駄だと思い、 singletonを使いました。 しかし、空欄チェックのときはnewでインスタンスを生成しています。 やはりこの場合もsingletonを使用したほうがいいのでしょうか? 仮にもっと複雑な問い合わせフォームを作成し、 利用者が多くなった場合、 いろいろとインスタンス化(空欄チェックや文字列チェック等)すると オブジェクトがたくさんできてしまい負荷がかかるで、 できる限り不必要なインスタンス化は避けたいと思っています。 長々と書いてしまい申し訳ありませんが、 なにとぞよろしくお願いします。

    • ベストアンサー
    • PHP
  • singletonメソッドへのアクセス

    インスタンスメソッドからsingletonメソッドへのアクセスが、思ったようにできません。 はじめは、次のように記述すれば動作すると思っていました。 (MyClass.get_hello_wordをインスタンスメソッドから呼び出し) class MyClass  def hello   puts self.get_hello_word # エラー発生源  end  def self.get_hello_word   'hello every one'  end end MyClass.new.hello # エラー しかし、実際には次のように記述しなければ動きませんでした。 class MyClass  def hello   puts self.class.get_hello_word # self.classのワンクッション  end  def self.get_hello_word   'hello every one'  end end MyClass.new.hello そもそも、 def self.get_hello_word と定義したんだから、参照する時も同様にできてもいいのではないかと思うんですけれど、何か認識が間違っているのでしょうか。 だとしたら、(勘で言いますと) class << MyClass  def get_hello_word   'hello every one'  end end の文法の考え方がからんでいるような気がするのですが・・ ちんぷんかんぷんです。 どうかこの辺りの知識を教えて頂けないでしょうか。 あと、self.class.get_hello_wordの記述方法よりも簡単な(そうすべき)書き方があれば教えて下さい。

    • ベストアンサー
    • Ruby
  • &や&=について

    --------------------------------------- class TextSanitizer { function &getInstance() { static $instance; if (!isset($instance)) { $instance = new TextSanitizer(); } return $instance; } } $myts =& TextSanitizer::getInstance(); ------------------------------------------- 上記について3点質問がございます。 1.【&getInstance()】の&は何を意味していますでしょうか? 2.【$myts =& TextSanitizer::getInstance();】の&=は何を意味していますでしょうか? 3.getInstance()関数はどんなとき使用すべきでしょうか? ご検討がつく方アドバイスを宜しくお願いします。

    • ベストアンサー
    • PHP
  • クラス、インスタンスメソッドについて

    JAVA初心者です。 現在、先人が作ったプログラムの修正作業を行っておりますが、 以下の点に疑問があります。(因みに、先人はJAVAのスペシャリストではありません。) あるクラスが以下の様になっております。 public class Sample { private static Sample s = new Sample(); private Sample() { } /** クラスメンバに存在するインスタンス取得 * @return Sampleクラスの唯一のインスタンス */ public static Sample getInstance(){ return s; } public static void methodA(){ ... } } でこのmethodAを使用するには、以下の様にします。 Sample.getInstance().methodA() これはこれで納得で、うまく動作しますが、これは 結局の所、クラスメソッドにしたかったという事ではないのかな?と 疑問に感じています。つまり、単純に Sample.methodA と呼び出せばうまくいきます。 ところが、たまたまAPIドキュメントを見ていた所、Calendarクラスにもやはり getInstanceというものが存在し、現在日時を取得するのに Calendar.getInstance().getTime() の様に呼び出すと書いてありました。 Sampleクラス、JAVAのCalendarクラス(これに限った事では無いとは思いますが) のこれらのgetInstanceの効用とはなんなんでしょうか? ・クラスの外でnewでインスタンスを作り出さない所 ・それでいてクラスメソッドではない(?)所 この辺りについてご回答よろしくお願いします。

    • ベストアンサー
    • Java
  • シングルトン内で使用したオブジェクトのGC

    基本的な質問で恐縮ですがGCについて教えてください。 例えば、シングルトンインスタンス内のhogemethodメソッドにてHashMapのインスタンスを 生成・使用した場合(以下の質問に続く)、 【質問】 hogemethodメソッドが終わればHashMapのインスタンスはスコープを外れるので、hogeMap = null;などしなくてもGC対象となり、そのうちGCされるのでしょうか?いやいや、hogeMap = null; することによりGC対象となり、そのうちGCされるのでしょうか?それとも、nullセットしようがしまいが、シングルトンのインスタンスが存在し続ける限りGC対象とはなってもGCされることは無いのでしょうか? package hoge; public class MySingleton {  private static MySingleton instance = new MySingleton();  private MySingleton() {}  public static MySingleton getInstance() {   return instance;  }  public void hogemethod() {   HashMap hogeMap = new HashMap();   hogeMap .put("りんご", "apple");   hogeMap .put("ぶどう", "grapes");     :   hogeMap = null; ←★hogeMap をGC対象にするためにはnull代入は必要なのか?  } } よろしくお願いします。

    • ベストアンサー
    • Java
  • Java リフレクションについて

    1.リフレクションを使い、値をセット(BeanのSetterメソッドにて) 2.1でセットした値を取得するために、下記コードで取得 Method Method = Class.getMethod("getLstData"); Object obj = Method.invoke(****); 上記の****の箇所には、メソッドのあるクラスのインスタンスを渡す、 というところまでは分かりますが、newInstance()してしまうと、新しいオブジェクトになってしまうので 値が取得できません。 error>>java.lang.IllegalArgumentException: object is not an instance of declaring class どのようにすれば、値の取得が可能でしょうか。 どなたかご教授いただければと思います。 ※Java 1.5を使用

    • ベストアンサー
    • Java
  • ご教示ください。

    ご教示ください。 javaで日付操作をやっています。 通常、クラスのインスタンスを作成する場合 クラス名 変数名 = new クラス名(); ですが、カレンダークラスを使用した際に Calender 変数名 = Calender.getInstance(); と出てきました。 Calenderクラスにある、getInstanceメソッドを呼び出していると思います。 クラスをインスタンスすることで、そのクラス内にある、メソッドやフィールドを初期値で使えて(コンストラクタがない場合)と認識しています。 インスタンスで、直接、メソッドを呼び出せる場合があるのでしょうか?

専門家に質問してみよう