- PR -

JAVAにおけるstaticメソッド

投稿者投稿内容
yamasa
ベテラン
会議室デビュー日: 2003/02/15
投稿数: 80
投稿日時: 2003-05-09 01:33
引用:

コレクションフレームワークと親和性が高いとは何を指していますか?


メソッド一つ実装するだけで、どのようなコレクション実装に対しても
同じ操作が提供できるということです。

実装は非常にシンプルなのに、汎用性は高いですよね。

引用:

Aというクラスに対してモデリングをする努力を放棄していませんか?
AのリストであるというモデリングをされたAListという実装をする努力を放棄していませんか?


モデリング至上主義全開の発言ですね。(笑)

別に「努力を放棄」しているつもりはありません。
「無駄な労力をかけない」ようにしているだけです。

当たり前のことですが、「モデリング」も「オブジェクト指向」も
手段であって目的ではありませんよね。
しかし、zaxx_MDさんの発言を読んでいると、
どうも「モデリング」そのものが目的化してしまっているような
印象を受けてしまいます。
ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2003-05-09 12:20
ども、ほむらです。
なにやら、モデリングについて新しいスレッドもほしくなる記事になりつつありますね。
モデリングとはなにか、とか(笑)
個人的には、設計によって分割できたインスタンスを機能で分割する作業を
モデリングというと思っていたのですが・・・
すこし違うのかなという疑問がでてきました。。
------------------
さて、表題の件ですがstaticにするものっていうのは、
クラス固有(または強く結びついた?)の処理をするけど、
インスタンス自体は作成されていなくても実行できるもの
で使うのだと思います。(主にフォーマット変換?)
こういう前提で行くと結局なくてもいいじゃんということにならなくてもないですが
インスタンスがなくても実行できるのに・・・・ということでstaticを使います。

ところで。。
yamasa氏の作り方は僕的にかなり共感がもてます。
クラスも無意味な肥大化しないし。機能分割もしっかりしているし・・・・・
ユーティリティクラスをパブリッククラスとしなくても
インナークラスで作成するだけでもメリットは高いし。。。
まぁこの場合は、ホントにカプセル化されてしまうので状況(設定)次第ですけど
うのきち
ベテラン
会議室デビュー日: 2003/02/17
投稿数: 55
投稿日時: 2003-05-11 11:50
引用:

例外処理はおいといて・・こういう実装とHashMapを拡張したAMapを別に作るべきでしょう。



でも、Map用のクラスと、List用のクラスに似たような集計処理が2つできるのがイヤじゃないですか?

一方、yamasaさんの案で、ひとつ気になるのは、

A a = (A) it.next();
sum += a.get();

この行ですね。これがあるために、class A専用になってる。値を取り出すためのゲッタオブジェクトを渡してやりたくなります。あと、これなら、staticにしなくても、いいと思うです。

public class Accumlation {
public interface Getter {
public int get(Object o);
}

protected Collection c;
protected Getter getter;

public Accumlation(Collection c, Getter getter) {
this.c = c;
this.getter = getter;
}

public int getSum() {
int sum = 0;
for (Iterator it = c.iterator(); it.hasNext(); ) {
sum += getter.get(it.next());
}
return sum;
}
}

class A {
int a;
A(int a) {
this.a = a;
}

int get() {
return a;
}
}

public class Test {
public static void main(String[] args) throws Exception {
List list = new ArrayList() {{
add(new A(1));
add(new A(2));
add(new A(3));
}};
int sum = new Accumlation(list, new Accumlation.Getter()
{
public int get(Object o) {
return ((A)o).get();
}
}).getSum();
System.out.println("Sum = " + sum);
}
}

とか。Accumlationクラスを継承して、SortedAcumulationクラスとか拡張することもできます。

ただ、Sumのように汎用的な操作の場合は、こうしますけど、class Aにしか通用しない操作が対象なら、class Aの中に実装するべきでしょうね。
うのきち
ベテラン
会議室デビュー日: 2003/02/17
投稿数: 55
投稿日時: 2003-05-11 11:55
う、見にくくてすいません。
スペースが削除されないようにするには、どうすればいいんでしょうか?
プリファレンス編集には、そういう設定無さそうだし。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-05-12 09:33
unibon です。こんにちわ。

引用:

ほむらさんの書き込み (2003-05-09 12:20) より:
さて、表題の件ですがstaticにするものっていうのは、
クラス固有(または強く結びついた?)の処理をするけど、
インスタンス自体は作成されていなくても実行できるもの
で使うのだと思います。(主にフォーマット変換?)
こういう前提で行くと結局なくてもいいじゃんということにならなくてもないですが
インスタンスがなくても実行できるのに・・・・ということでstaticを使います。


おっしゃることにうなずけます。

思うに、インスタンスに結びつく必要不可欠なプリミティブなオペレーションではなく、
それらプリミティブなオペレーションを呼び出す組み合わせだけを定義したメソッドなら、
プリミティブなオペレーションと明確に区別する意味でも static にしたほうが良いと思います。
もちろん、このやりかたで行く場合、
たとえば、すべてのフィールドごとに getter/setter メソッドを設けてしまうと、
それらの getter/setter がプリミティブなメソッドになってしまい、
それ以外のメソッドがすべて static になってしまうので、
このように getter/setter を設けるのは避けるべきです。
また、このような getter/setter に近い荒さのメソッド
(フィールドを操作する1行だけ、とまでは行かないにしてもせいぜい数行だけのメソッド)も、
たくさんうかつに作ってしまうと、
重要なメソッドも static にできてしまい、雑魚のメソッドとの区別が付かなくなり、
これもヘンだと思います。

ということで、メソッドを static にするかどうかの問題は、
カプセル化との兼ね合いと密に絡んでいるのだろう、と感じました。



#以下、あとから追加しました。

引用:

北斗のポンさんの書き込み (2003-05-08 17:53) より:
アプリケーションの規模や、他のクラスとの関わり、etcなど条件はいろいろあるのでしょうが、staticメソッドを作成する再にそのメソッドをstaticにした境界線みたいなものってなんでしょうか?


これについての私なりの回答としては、
static にする・しないの境界というのは、直接の問題ではないと思います
(言い過ぎかもしれませんが、瑣末な問題だと思います)。
それ以前に、上述のようなプリミティブなメソッドを作り過ぎてしまうと、
その他のメソッドを static にできてしまえる背景ができてしまい、
その結果としてメソッドを static にするかどうかを迷ってしまうことになってしまうのだろう、
と思います。
すなわち、static にするかどうかが問題ではなく、
その前に、容易に static にできてしまうほど、カプセル化がされていないかどうかが問題です。
ただし、雑多な機能をアドオンする、というような位置付けで新たに作るメソッドならば、
static になる(できる)のは悪いことではないと思います。

引用:

北斗のポンさんの書き込み (2003-05-08 17:53) より:
staticメソッドは極力使用しないほうがいいということは「わかって」はいますが「理解」はしてい無いように思います。


私の最初の投稿で触れましたが、
(a) static フィールドを操作する static メソッドか、
(b) static フィールドを操作しない static メソッドかは、
大きな違いがあります。
この内、(a) はかなりシビアであり、使わないほうが良いと言える場面も多々ありますが、
一方、(b) のほうならば上述のように「瑣末」な問題と言えると思います
(改善するとしたらそれより以前の段階だと思います)。
すなわち、(b) については static は付けても付けなくても、表面的な差だけです。
最初のうちはあまり拘らなくても良いと思います。

[ メッセージ編集済み 編集者: unibon 編集日時 2003-05-12 11:32 ]
ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2003-05-12 10:48
ども、ほむらです。
-------------------

うのきちさんへ
引用:

一方、yamasaさんの案で、ひとつ気になるのは、

A a = (A) it.next();
sum += a.get();

この行ですね。これがあるために、class A専用になってる。値を取り出すためのゲッタオブジェクトを渡してやりたくなります。あと、これなら、staticにしなくても、いいと思うです。


クラスの名前が AUtils ということになっているのでclass A専用でよいと思います。
逆にA::getSum()はClass A というオブジェクト内の
データの合計を求めるメソッドなのですからClass A以外のことを
考えるべきでは無い様にも思います
オブジェクト内からデータを取り出す過程でA::get()というメソッドを使用したほうが
カプセル化されていて、かっこいいし(笑)

ちなみに、getSum()のような合計を求めるメソッドがある場合にはインナーで作るより
外に出してしまったほうがメリットも高そうですね
(普通は合計を求めるのは外部クラスでしょうし)

unibonさんへ
引用:

ということで、メソッドを static にするかどうかの問題は、
カプセル化との兼ね合いと密に絡んでいるのだろう、と感じました。


カプセル化って難しいですよね。厳密に作りたいけどやりすぎると
外部からアクセスできなくなってしまったり、
気が付けば細かいメソッドが大量に出来てしまったりして。。。

結局は慣れだよ。。なんて事に行き着きそうですが
このあたりの見極めがはやくできるようになりたいです><。
zaxx_MD
大ベテラン
会議室デビュー日: 2003/04/21
投稿数: 204
お住まい・勤務地: 千葉県柏市
投稿日時: 2003-05-12 16:52
色々とレスが付いていてどれから返答すればいいのか悩むところですが。

 メソッドをstaticで作るかどうかは状況しだいでどちらでもいいのですが、
チームとして業務アプリケーションを開発する場合、
他のメンバーとモデルを通して処理の相互理解ができるほうが
格段に効率がいいわけです。
 そして、staticで手続き処理の書き方をしてしまうと、
非常にモデリングしにくくなってしまう。
 だからstaticでメソッドを作るか作らないかを判断する際にモデリングをどこまでするか
決めればいいでしょうというのが当初の私の結論です。

まずはそれだけ言わせてもらいます。
個別のレスはまた後日ということで・・
zaxx_MD
大ベテラン
会議室デビュー日: 2003/04/21
投稿数: 204
お住まい・勤務地: 千葉県柏市
投稿日時: 2003-05-12 17:32
無視しようかとも思ったのですが・・
非常にいいことをおっしゃっているので、そこをまず・・
引用:

悪夢を統べるものさんの書き込み (2003-05-08 18:54) より:
設計さえ決まれば,どの部分がインスタンスになり,どの部分が
インスタンスメソッドになり,どの部分がstaticメソッドになるか,概ね決まって
きます.最後までどちらにするか悩む部分もありますが,こういう部分はどちらで
実装しても構わない場合が多かったりします.


この通りで悩まないで決まったりします。
しかし、いつでも詳細設計まで考慮された設計が落ちてくるというのは
ありえない話で、ご都合主義でしかありません。

引用:

多分,問題なのはstaticメソッドかnon-staticメソッドかではなく,
「より適切なOOPらしい,良い設計はどんなものか」
だと思います.
#決してモデリングじゃありません.

・・・

で,どうすれば良い設計ができるかですが,これについては一言では
説明できません.(それができるなら,私はOOPの講習会を開いて大金持ちに
なれるでしょう.(^^) )GoFのデザインパターンとかリファクタリングとか
そう言った良書でも読みながら,少しずつ真似をして理解を深めていく
他ないと思います.



OOPもGoFのデザインパターンも今日のWebApplication構築には意味をなさない場合が多くなってきました。
そういう意味をこめて敢えてモデリングという言葉を使っていきたいと思います。
実際GoFのデザインパターンの全てを一度でも使う機会はありましたか?
彼らの意図を汲み取ることは非常に重要ですが、
(難しい)アプリケーション構築をしていく上ではもう一歩実践的な考え方が必要です。

OOPの悪いところは赤いりんごの赤とボールペンの赤は違うものだというところでしょうか。
うまく説明できませんが・・
(りんごの色素から抽出したインクを使っているというのは微妙にナシです)
こういう厳密なオブジェクト指向は業務のコーディングを進めていく上では
無意味だったりします。(ごく稀に必要な場合もありますが)
 また具体的な問題としては、リフレクションを使ったり、
Javaのsuper classが一つしか定義できないところはOOPから外れているところですが、
そういうコーディングの方が効率がよかったりポリシーとして正しい場合もあります。

ですからSmallTalk時代の用語を多用するよりはモデリングという言葉で逃げたほうが
良くないですか?もっと緩やかなカプセル化の方が実用的です。

緩やかな口調での誠実な回答をお待ちしています。

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