- PR -

変数の値に応じてgetterを呼びたい

投稿者投稿内容
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2004-09-02 18:24
unibon です。こんにちわ。

Perl とかだと良く使われるみたいですが、メタデータを動的に扱うことは Java など型を強く意識する言語ではあまりやりません。Java にはリフレクションの API も豊富にありますが、こういう API は普通のアプリケーションで使うのではなく、IDE などの統合環境やデバッグ環境の実装のために使うために存在意義があるのだろうと考えます。
なぜダメ(普通のアプリケーションでは使うべきではない)かといえば、コストがかかりすぎるからです。単に速度的なコストというのではなく、なんて言うんでしょうかコードが汚くなるからです。別に便利なら使えば良いのでは、という考えもあると思います。ポリシーの違いだけなのかもしれません。別にいいのかなあ、使っても。

クラスの中のものを外にさらけ出したいような場合に、リフレクションとかイントロスペクション絡みの機能を使わないでやろうとすれば、Iterator のパターン(正確な分類はなにになるのかは良く分からないのですが)を使うことが多いと思います。今回の場合は Runnable 型のインスタンスを列挙する Iterator のパターンを使うと良いのではと思います(Runnable じゃなくても良いですが)。
http://java.sun.com/j2se/1.4/ja/docs/ja/api/java/util/Iterator.html
サンプルコードを書こうと思ったのですが、ちょっととっかかりが分からなかったので書けませんでした。後日、もし書ければ書きます。
Cluster
ぬし
会議室デビュー日: 2003/03/06
投稿数: 289
お住まい・勤務地: 大阪
投稿日時: 2004-09-02 18:37
BeanInfoPropertyDescriptorで実装可能だと思いますが、
みなさんが先に言ってる通り、コード作成の省力化程度の理由なら
使わないほうがいいと思いますよ。
holic
ベテラン
会議室デビュー日: 2004/08/24
投稿数: 74
投稿日時: 2004-09-02 19:10
引用:

なぜダメ(普通のアプリケーションでは使うべきではない)かといえば、コストがかかりすぎるからです。単に速度的なコストというのではなく、なんて言うんでしょうかコードが汚くなるからです。別に便利なら使えば良いのでは、という考えもあると思います。ポリシーの違いだけなのかもしれません。別にいいのかなあ、使っても。



通常のアプリケーションの実装点で、リフレクションを使うのはよろしくない、というのには賛成します。ただ、通常の実装者が触ることのないフレームワーク部分などで使うのにメリットがあるのであれば問題ないと思います。Struts も BeanUtils 経由でリフレクションを駆使していますよね。

まあ、この最初の投稿については、配列を返すメソッドを追加するくらいで十分かなという気はしていますが。
banboo
大ベテラン
会議室デビュー日: 2003/12/05
投稿数: 210
投稿日時: 2004-09-02 22:11
皆様、いろいろと有用な情報を教えていただき
ありがとうございます。

最終的には、以下のようにしました。

フィールドの中で,用途に応じて
分けました。

1. clientの情報

キーと値のペアが
storeClient に蓄積される

2. serverの情報

キーと値のペアが
storeServer に蓄積される

3.idに関する情報

各フィールドを持つ(setter/getter)

1,2の情報については、
キーをまとめて取り出し、
そのキーに応じて値を取り出しました。

(一番最初に私があげた例で言うと
フィールドの値に応じてgetterを呼びたいと考えております。
イメージとしては、
String value_ = uInfo.get$Foge();
にあたります。



Set set = storeClient.keySet();

Iterator iterator = set.iterator();

while (iterator.hasNext()) {
String key = (String) iterator.next();

String value = (String) uInfo.get(key, 0);<---

if (value != null) {
System.out.println("value = " + value);
}

}

ここで、下記のようにプログラムは、

setter/getter と
Mapを使用することによる
set/get
が同居しております。
しかし自分自身、

・このクラス設計(データ構造)でそもそもいいのか?
・もっとエレガントな書き方があるのか?

といった点で疑問が残ります。もしよろしければ
アドバイスを宜しく御願い致します。




----------------------------

import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class UserTest {

public static void main() {

UserInfo3 uInfo = new UserInfo3();

uInfo.setMachineIDClient("002");

uInfo.setMachineIDServer("002_");

uInfo.set("IPAddress", "192.168.10.1", 0);

uInfo.set("machineTerminalClient", "note-pc", 0);

uInfo.set("machinePriceClient", "200000", 0);


uInfo.set("IPAddress", "192.168.10.2", 1);

Map storeClient = uInfo.getStoreClient();

Set set = storeClient.keySet();

Iterator iterator = set.iterator();

while (iterator.hasNext()) {
String key = (String) iterator.next();

String value = (String) uInfo.get(key, 0);

if (value != null) {
System.out.println("value = " + value);
}

}

}

}

---------------------------------
import java.util.HashMap;
import java.util.Map;

class UserInfo3 {

private Map storeClient = new HashMap();

private Map storeServer = new HashMap();

private String machineIDClient;

private String machineIDServer;

private String userIDClient;

public void set(Object key, Object value, int flag) {

if (flag == 0) {
storeClient.put(key, value);
} else {
storeServer.put(key, value);
}
}

public Object get(Object key, int flag) {

if (flag == 0) {
return storeClient.get(key);
} else {
return storeServer.get(key);
}

}

/**
* @return
*/
public Map getStoreClient() {
return storeClient;
}

/**
* @param map
*/
public void setStoreClient(Map map) {
storeClient = map;
}

/**
* @return
*/
public Map getStoreServer() {
return storeServer;
}

/**
* @param map
*/
public void setStoreServer(Map map) {
storeServer = map;
}

/**
* @return
*/
public String getMachineIDClient() {
return machineIDClient;
}

/**
* @return
*/
public String getMachineIDServer() {
return machineIDServer;
}

/**
* @return
*/
public String getUserIDClient() {
return userIDClient;
}

/**
* @param string
*/
public void setMachineIDClient(String string) {
machineIDClient = string;
}

/**
* @param string
*/
public void setMachineIDServer(String string) {
machineIDServer = string;
}

/**
* @param string
*/
public void setUserIDClient(String string) {
userIDClient = string;
}

}

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