- PR -

インスタンス生成について

投稿者投稿内容
jack
常連さん
会議室デビュー日: 2002/07/24
投稿数: 22
投稿日時: 2003-01-16 02:47
基本的なことだと思うのですが、素朴な疑問がありますので
どなたかご教授ください。調べてはみたのですが、資料がなくて・・・

インスタンス生成には負荷がかかるとお聞きします。なので、
できるだけインスタンス生成の回数を減らした方がいいのでは
ないかと思います。というか、データを保持してもいいオブジェクト(クラス)
ならば一回だけにするのがいいのでは無いでしょうか?

-------------------------------------
class B
{
 void methodC(){}
 void methodD(){}
}

public class A
{
 public static void main(String args[])
 {
 }

 void methodA()
 {
  B b = new B();
  b.methodC();
 }

 void methodB()
 {
  B b = new B();
  b.methodD();
 }
}
-------------------------------------

とするなら・・・

-------------------------------------
class B
{
 void methodC(){}
 void methodD(){}
}

public class A
{
 public static void main(String args[])
 {
 }

 B b = new B();

 void methodA()
 {
  b.methodC();
 }

 void methodB()
 {
  b.methodD();
 }
}
-------------------------------------

参照変数を一度だけ生成すれば、そのクラスではどこでも
そのオブジェクトを使えるようになってインスタンス生成は
一度だけで済みますよね?
この方法は何か良くないのですか?

また冒頭に「データを保持してもいいオブジェクト」と素人なりに
考えた表現を使わせてもらいましたが、クラスをnew演算子で生成すると
そのクラスのデータが初期化されてしまいますよね。プログラミング
をしているとたまにこれで困ってしまい、データを保持していて欲しい
クラスは全てSingletonで作成し、new演算子で生成しないようにしています。
このような場合、他の手法などはあるのでしょうか?




[ メッセージ編集済み 編集者: jack 編集日時 2003-01-16 02:49 ]
みやも
ベテラン
会議室デビュー日: 2002/04/22
投稿数: 74
投稿日時: 2003-01-17 01:11
>参照変数を一度だけ生成すれば、そのクラスではどこでも
>そのオブジェクトを使えるようになってインスタンス生成は
>一度だけで済みますよね?
>この方法は何か良くないのですか?

カプセル化が損なわれ、
Cの時代のグローバル変数の悪魔が再来します。


>インスタンス生成には負荷がかかるとお聞きします。なので、
>できるだけインスタンス生成の回数を減らした方がいいのでは
>ないかと思います。というか、データを保持してもいいオブジェクト(クラス)
>ならば一回だけにするのがいいのでは無いでしょうか?

インスタンス生成にかかる負荷というのは、
アプリケーション全体のほんの一部です。

パフォーマンスが問題になる一部分についてのみ、
FlyWeightやオブジェクトプーリングといった手法を使うべきだと思います。

分かりやすさのためか、パフォーマンスに関する誤った憶測のためか、
世の中には何でもかんでもstaticメソッドにしよういうコーディング規約もあるらしい?ですが。
jack
常連さん
会議室デビュー日: 2002/07/24
投稿数: 22
投稿日時: 2003-01-17 05:05
書き込みありがとうございました。

>カプセル化が損なわれ、
>Cの時代のグローバル変数の悪魔が再来します。

「なるほど」と思いますが、もう少し説明して
いただけないでしょうか?

このプログラム例ような場合、Bクラスのフィールドの
「今の状態」を、Aクラスのどこからでも取得できると思います。
それを意図して作成しているのですが。
しかし、Aクラスのその場その場でインスタンスを生成していると、
その度にフィールドが初期化されてしまいますよね。

なので、このようにクラスの参照変数をグローバルにするか、
Singletonを用いてstaticクラスとして作成しなければ、データを
保持できないのではないかと思います。
つまり、そのようなオブジェクトは「一度しか生成しない」ことが
必要かと思います。

本当に素人なので、これ以外の事が思いつかないのです。
私はシステムと呼べるほどの物を作ったことはありませんが、
システムを作成すると、いくつかの処理で必要になるいくつかの
「データ」というものが存在するかと思います。その時、それらの
データを格納するクラスというものはstaticなクラスでないと
利用(インスタンスを生成)するときにデータが失われてしまいますね。

このような時の定番の方法などがあったら教えてください。
いろいろな人の手法を聞いてみたいです。
H2
ぬし
会議室デビュー日: 2001/09/06
投稿数: 586
お住まい・勤務地: 港
投稿日時: 2003-01-17 06:59
引用:

なので、このようにクラスの参照変数をグローバルにするか、Singletonを用いてstaticクラスとして作成しなければ、データを保持できないのではないかと思います。つまり、そのようなオブジェクトは「一度しか生成しない」ことが必要かと思います。


確かに間違っていはいませんがちょっと補足を。Singletonタイプともう一つの方法には決定的な違いがあります。

Singletonを使うのはアプリケーション上で、そのオブジェクトが一つだけしか必要がない時です。

クラスの参照変数をフィールド変数にするのはそのクラスのオブジェクト内で生成されるのが一回だけの場合です。この方法が一般的だと思います。というか他の方法って?ちなみにJavaではグローバルではなくフィールド変数といいます。カプセル化を図るため、privateにしておくことをお勧めします。

Singletonは便利ですが、後々の拡張が難しくなるのと同期な問題も起きるので本当に必要な状況で使うべきです。

引用:

分かりやすさのためか、パフォーマンスに関する誤った憶測のためか、
世の中には何でもかんでもstaticメソッドにしよういうコーディング規約もあるらしい?ですが。


それってオブジェクト指向じゃない・・・ とほほな規約ですねぇ。
jack
常連さん
会議室デビュー日: 2002/07/24
投稿数: 22
投稿日時: 2003-01-17 20:28
>確かに間違っていはいませんがちょっと補足を。Singletonタイプともう一つの
>方法には決定的な違いがあります。

>Singletonを使うのはアプリケーション上で、そのオブジェクトが一つだけしか
>必要がない時です。

たしかにその通りです。大事なことを書くのを忘れていましたね。
また、フィールド変数をグローバル変数と呼んでいたのは
まるでJava初心者がばれてしまいました。恥をかいてしまいましたね(--

でも「確かに間違っていはいませんが」ということで安心しました。

>Singletonは便利ですが、後々の拡張が難しくなるのと同期な問題も起きるので
>本当に必要な状況で使うべきです。

まだ経験が少なく、このようなことを実感したことがないので
どのようなところでこれを実感するのかが分かりませんが、
これに突き当たったときに考えたいと思います。



[ メッセージ編集済み 編集者: jack 編集日時 2003-01-17 20:29 ]
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-01-20 17:00
unibon です。こんにちわ。
#以下、遅い投稿で、かつ、難しい内容かもしれませんが。

引用:

jackさんの書き込み (2003-01-17 05:05) より:
このプログラム例ような場合、Bクラスのフィールドの
「今の状態」を、Aクラスのどこからでも取得できると思います。
それを意図して作成しているのですが。


見方にもよりますが、
「リファクタリング」における「値から参照への変更」をすべきかどうか、
の問題に相当すると思います。
ちなみに、
http://www.pearsoned.co.jp/washo/object/wa_obj25-j.html
の「第8章 データの再編成」の中で取り上げられていますので、
もしお持ちならばご参考までに。

また、今回の場合は、参照に変更した場合は、どうやって参照を維持するか、
という問題が、これに付随して新たに出てきているのだと思います。
参照の維持は、static(や Singleton)を使うか使わないかといった選択肢もありますが、
ここでは触れないことにします。
jack
常連さん
会議室デビュー日: 2002/07/24
投稿数: 22
投稿日時: 2003-01-22 01:31
ありがとうございます。紹介してくださった本を是非読んでみたいと
思います。やっぱ、色々な本に目を通してみることは大切ですね。
今のエンジニアがどのような本を参考にしてきたのかを知ることが
できるのは嬉しいです。

正直、「リファクタリング」が何かも分からないので、これを勉強して
少しでも何か得るものがあれば言いと思います。

知り合いにBasicやCOBOLを使っていたエンジニアがいますが、その人
いわく、大目に見れば「プログラムは完全に要求を満たす動作をすれば
どのようなコードでもかまわない」と言っていました。
それが、オブジェクト指向やJavaの出現により大きく変わった気がします。
それによりプログラミングがさらに難しくなり、美しいコード(抽象的ですが)
を求めるようになってきました。
しかし、だからこそはまってしまうのでしょうか
犬び
会議室デビュー日: 2003/01/22
投稿数: 1
投稿日時: 2003-01-22 12:34
変数のスコープについては昔からポリシーはさほど変わっていないはずです。極力狭く!です。スコープが広くなればなるほど、その変数がどこで書き換えられるかわからない恐怖に怯えることになります。ですから、メソッドローカルな変数でだめならprivate,privateでだめなら・・・とスコープを広げることはある種の諦めだと思っておいた方が良いかもしれません。
今更遅いかもしれませんが、最初の例の場合にはmethodC,methodDの性質にもよります。これらのメソッドがクラスBの状態に依存しないものであればstaticメソッドとして実装しておくのも良いとおもいます。

オブジェクト指向でプログラミングが難しくなったといわれればそうかもしれませんが、OOは人間に分かりやすい表現方法を模索した一つの結果です。ですから、従来の言語よりもより自然にプログラムを記述できるはずなのです。
ただ、実現の為の記述方法の選択肢が増えた為にかえって頭を悩ませることが多くなったという罠でしょうね。

スキルアップ/キャリアアップ(JOB@IT)