[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 11035] ValueObjectProxy の詳細 情報



井上泰です。

ValueObjectProxyの詳細情報です。

ValueObjectProxyは、"Java Enterprise Best Practices"のp11-13にあります。
http://www.amazon.co.jp/exec/obidos/ASIN/0596003846/qid=1077961015/sr=1-10/ref=sr_1_10_10/250-1021153-8339448

コードをそのまま引用できないので、ValueObjectProxyを参考に作ったクラスを
下に示します。
# DTO自動生成機能があれば、必要性ないかもしれません

----
EJBパターン第2回で、村上さんが指摘されたStrutsEJBは変形版のようです。
https://strutsejb.dev.java.net/index_ja.html
jp.co.sth.common.dto.DTOProxyFactory

# DTOProxyFactoryの詳細はこれから読むつもりです。

=============================================================
ValueObjectProxyを参考に作成したコードです。
# toString()は井上が追加しました。

使い方は、以下のようになります。

インターフェイス vo = (インターフェイス) ValueObjectProxy.createValueObject(
インターフェイス.class);

// vo はインターフェイスで定義したsetter/getterを持つDTOとして使用するこ
とができる。
// ValueObjectProxyはsetter/getterを横取りして、HashMapを利用する。

-------------------
利点
DTOの本体は一つだけ記述するので簡単
CMPのクラスからコピーしてDTOのインターフェイスを作成しやすい
コンパイル時に型チェックができる
欠点
間接実行するので速度は遅いだろう
DTOのそれぞれに必要な機能を追加しにくい。例えば、validate()など
---------------------------------

import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Iterator;
import java.util.Collection;
import java.util.HashMap;

public class ValueObjectProxy implements InvocationHandler, Serializable {

protected HashMap fieldMap;
protected Class valueObjectClass;

protected ValueObjectProxy(Class valueObjectClass) {
this.valueObjectClass = valueObjectClass;
fieldMap = new HashMap();
}

public static Object createValueObject(Class valueObjectClass) {
if (valueObjectClass == null) {
throw new IllegalArgumentException("argument class is null");
}
return Proxy.newProxyInstance(
valueObjectClass.getClassLoader()
,(new Class[] {valueObjectClass})
,(new ValueObjectProxy(valueObjectClass))

);
}

public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
Object result = null;
String methodName = method.getName();
if (methodName.startsWith("get")) {
String fieldName = methodName.substring(3);
if (fieldMap.containsKey(fieldName)) {
result = null;
}
result = fieldMap.get(fieldName);
} else if (methodName.startsWith("set")) {
String fieldName = methodName.substring(3);
fieldMap.put(fieldName, args[0]);
result = args[0];
} else if ("toString".equals(methodName)) {
toString();
} else {
throw new IllegalArgumentException("this method is not supported");
}
return result;
}

private static final String LF =
System.getProperties().getProperty("line.separator");

public String toString() {
StringBuffer sb = new StringBuffer();

Iterator it = fieldMap.keySet().iterator();
for (String name=null;it.hasNext();) {
name = (String)it.next();
sb.append(name);
sb.append("='");
sb.append(fieldMap.get(name));
sb.append("'");
sb.append(LF);
}

return sb.toString();
}

}