- - PR -
新人SEのためのJava講座についての質問
«前のページへ
1|2|3
| 投稿者 | 投稿内容 | ||||||||
|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2002-12-19 09:46
永井@Java初心者です。 自分がstaticメソッドを定義するのは、オブジェクト同士の演算やフィルタの場合が多いように感じます。 言い換えれば、 オブジェクトの状態を変化させることに意識主体がある場合にインスタンスメソッド、 オブジェクトの状態が変化するかどうかには興味が無く(もしくは、むしろ明示的な変化は望まず)、オブジェクト間の関係やデータの一部を取得したいときにクラスメソッド、 という感じで使用しています。 例えば、ClassAのインスタンスaとbをオブジェクト的に和算したものをcに格納したい場合、 ClassA a = new ClassA(); ClassA b = new ClassA(); ClassA c = new ClassA(a); c.add(b); と書くのは冗長で不便に感じますので、 ClassA a = new ClassA(); ClassA b = new ClassA(); ClassA c = ClassA.sum(a, b); と書く感じです。 フィルタのケースですと ClassA a = new ClassA(); ClassA b = a.convert("format"); ではaの状態までformatに合う形式に変化してしまいそうな感じがするので ClassA a = new ClassA(); ClassA b = ClassA.filter(a, "format"); と書きたくなります。 #と、ここまで書いててふと思いましたが、この考え方でいくとsetterは #インスタンスメソッド、getterはクラスメソッドとかいう面白い構造になったり #するんでしょうか ## ClassA a = new ClassA(); ## a.setMemberA(1); ## int b = ClassA.getMemberA(a); ## 駄目だ……不自然過ぎる(^^; | ||||||||
|
投稿日時: 2002-12-21 19:05
その「最近の流行」で重視しているのは、「システムをシンプルに保てば、将来どんな変更が必要になっても迅速に対処できる」という点です。 なので、
ここは「その未来予測が的中した場合だけ楽ができる」となります。予想外の変更が必要になった場合(税制がガラリと代わるなど)は、そうした設計やコードの煩雑がいたるところで足を引っ張り、泥沼となるでしょう。 「策士、策に溺れる」というのは、ベテランでも陥りやすい罠です。 | ||||||||
|
投稿日時: 2002-12-24 13:43
unibon です。こんにちわ。
私が自分でネタ(「最近の流行」)を書いておきながら、 でどころなどが良く分かっていないので、 なにを重視するのかは良く分かっていないのですが、 static を使わないようにしたからといって「複雑」になるわけではないと考えます。 ただし、必要ゆえの「煩雑さ」は残ると思います。 #コードは「煩雑」だけど「複雑」にはなるわけではない、という、(へ?)理屈です。 たとえば煩雑さを避けて static フィールドを使ってしまい、 あとから static フィールドゆえに困る具体的な例としては、 Singleton の実装があると思います。 Singleton の実装としては、よく static のフィールドで管理する例を、よく目にします。 しかし static で管理してよいのは、 あくまでもひとつの VM 内でひとつのモノに限定したい場合に使うべきであり、 逆に言えば、この場合にこそ VM の存在に密に連動する static を使うべきです。 それ以外の場合、VM に一対一に対応しないインスタンスになる可能性のものは、 static を使うべきではないと思います。 たとえば、アプリケーションに依存した、ビジネスロジックにまつわるインスタンスは、 必ずしも VM と一対一に対応するとは限らないと思われるため、 税率等のビジネスロジックには static を使うべきではないと思います。 安易に static を使ってしまうと、後から非 static にしようとした場合、 Single にしたいスコープの定義がプログラムには残っていないため、 設計にまで戻らざるを得なくなります。 それならば、コーディング時に static を使わないようにしておけば、 自然に Single のスコープの定義も、どこかの段階で考えざるをえず、 設計がきっちりできてよいと思います。 具体的な例としては、 あるアプリケーションをいままではひとつの VM 上で、 ひとつのアプリケーションウィンドウを開いていたが、 これをひとつの VM 上で複数のアプリケーションウィンドウを開くことができるようにしたい場合です。 アプリケーションウィンドウでなくても Servlet などでもこのような場面はあると推測します。 #ようはできるだけ VM を共有して、その上で複数のインスタンスを扱いたいようなケースです。 このような場面で、Singleton を static で使っていると、 Singleton にはしておきたいけど、でもアプリケーションのインスタンスごとの単位では分けたい、 ということがありますが、そのようなときに困るはずです。 ちなみに、これは static フィールドだけではなく、 static フィールドにアクセスする static メソッドにもまつわる問題だと思います。 ただし static フィールドにアクセスしない static メソッドならば、 フィールドに無関係のコード(処理)の置き場でしかないので、関係のない話ですが。 | ||||||||
|
投稿日時: 2002-12-25 18:13
unibonさん:
この問題は、以前別のスレッドでやってた「フィールドかメソッドか」の論争に関係してきます。 要するに、オブジェクト指向において分析や設計の段階で何を公開し何を隠蔽するか、ということです。 「staticフィールドを使うかどうか」ということは実は全く瑣末な問題であって、本質は「外部に公開する情報を絞り込んで、インターフェイスをシンプルに保つ」という点にあります。 unibonさんのおっしゃるように、staticフィールドを直接アクセスするコードが散らばっていることが問題になることはありえます。しかし、publicなフィールドでない限りは、たいした事はありません。クラスの外部からはstaticメソッドを介してアクセスしていれば、問題ないわけです。 これに対して、「税率クラス」などを導入して直接参照するとなると、外部に公開される要素が増えることになり、複雑さが確実に増します。これは、拡張性と引き換えにするには高いコストとなります。 わたしなら、こうした場合は税率を取得するstaticメソッドを用意しておき、税率そのものの実装方法は隠蔽しておきます。そして、当初はstaticフィールドで保持しておき、顧客が「海外展開」などを計画した時点で、実装だけを切り替えるわけです。 単一アプリケーションからAPPサーバへの変更も同様です。 ようするに、設計段階で「インターフェイスをシンプルに保つ」ことに集中すれば、自然と実装詳細などは隠蔽されていき、仕様の変更にも対応しやすくなる、ということです。 だったら、当たるかどうかわからない未来予測などやめてしまおう、となりませんか? | ||||||||
|
投稿日時: 2002-12-25 21:46
ども。「税率」言い出しっぺのraccoonです。
わたしもだいたいそのようなイメージでした。あまり具体的には考えていませんでしたが・・・。 わたしは「メソッド重視派」なのですが,以前の書き込みでは
と書いてしまいました。 これは,「結果が同じになってもアプローチが違う」ということを言いたかったもので, 「メンバをどう持つかは本来問題ではない」と考えています。 # この文章じゃ伝わりませんね。すみません・・・ # へげもんさんに代弁していただいた形になりますね。ありがとうございます。 拡張性についてですが, 「インタフェースをシンプルに保つ」のは,仕様変更だけでなくバグ修正などにも有利なので, 広い意味での保守性として心がけています。 「シンプル」の解釈が人によって異なるかも知れませんが,わたしの場合は 「インターフェースがシンプル=クラス間の関係が疎=カプセル化がしっかりできている」 と捉えています。 staticメンバやメソッドを使うと,クラス間が密になる誤りを犯しやすいのは確かですが, うまく隠蔽する設計になっていれば,staticを使っても使わなくても,クラス関係を疎に保ち, シンプルなインタフェースとすることができるのではないでしょうか? # ということは,static/非staticは拡張性には関係ない? # これでは最初の疑問に戻っちゃう? | ||||||||
|
投稿日時: 2003-01-06 16:31
unibon です。こんにちわ。
このスレッドにどの程度関連するかはちょっとあやふやですが、 最近、たまたま見つけたものとして、 JavaHouse-Brewers の6年前の記事に static についての話題がありました。 http://java-house.jp/ml/archive/j-h-b/008990.html や、その前後です。 | ||||||||
|
投稿日時: 2003-01-06 19:31
unibon です。こんにちわ。
思い出したのですが、servlet の場合はインスタンス変数(static ではないフィールド)も 複数の request 間で共有されるので、 servlet のようなマルチスレッドの環境では、 クラス変数(static なフィールド)以外にも、 インスタンス変数を共有すべきか、という問題が servlet 以外の static フィールドの場合と同様にあることに気づきました。 #気づいたというだけなのですが。 なんだか共有のレベルがネストするような感じでややこしいですね。 #余談ですが、私は servlet はサンプル程度のものしか知らないので、 #なぜ servlet のインスタンス変数が共有されるようになっているかの理由をよく知りません。 #HttpServlet 型のインスタンスを request ごとに new するコストすらも #なくそうとしたためなのかな、と漠然と思っていますが。 | ||||||||
|
投稿日時: 2003-01-07 20:34
こんばんわ、YKIDです。
http://java-house.jp/ml/archive/j-h-b/050455.html ここにかなり的確な答(だと思われる)が記述されています。 参考までに。 [ メッセージ編集済み 編集者: YKID 編集日時 2003-01-07 20:37 ] | ||||||||
«前のページへ
1|2|3
