変奏現実

パソコンやMMORPGのことなどを思いつくまま・・・記載されている会社名・製品名・システム名などは、各社の商標、または登録商標です。

この画面は、簡易表示です

2013年10月3日

JavaのBean

実体は、
private なプロパティにSetter/Gettorを付けただけのもの。

class  xxxBean {

private int aaa;

int getAaa(){ return aaa; }

void setAaa( int aaa) { this.aaa = aaa; }

}

これが美味しいのは、
ちょこっとコードを付け加えると、容易に似たものがいっぱい作れるからだ。
例えば、
void setGMT(Date gmtTime) { this gmt = gmtTime; }
で時刻をセットしたら、
Date getJst() /* 日本 */         { return gmtTime  + 9 hour; }

Date getEst() /* アメリカ西部*/{ return gmtTime  –  9 hour; }

Date getEt() /* アメリカ東部*/{ return gmtTime  –  5 hour; }
で判れば便利だからだ。
でも、全世界分のメソッドを作っても、賞味期限は不明なので、別のやり方(Locale)で延命している。
Localeでも新しい標準時刻が規定されれば、新しいstatic Locale を追加しなければならないが、メソッドそのものを追加する必要はない。
だが、50歩100歩なので、実際は大きな差は無い。
新しいメソッドを追加しないと国際問題になるが・・・
新しいstatic Localeを追加しなくても
代用で済むならOKな世の中の情勢によるところが大きい。
このBeanを使うと全てのメソッドは大雑把に

XxxBean   aMethod (YyyBean)

に纏めることができる。
が、それはC言語どころかCOBOLでもBASICでも同じで、できないのは古い版のFORTRANぐらいなものだ。
※構造体の概念が欠落しているからね。
しかし、JavaだけBeanとか言っているところが、幼い感じがする。
そう、今のJavaは幼い。
見の丈が足らない。
例えば、インターフェースのための、ヘッダーファイルを定義できない。
インターフェースとして外殻だけだがクラスとしての実態を持たなければいけないので、
インジェクションによる初期化が必要なクセにそのコードの実装は実に巧みに隠しているため、
ソース上は丸く収まっても、実行してみれば・・・インターフェースのオブジェクトの実体はnullポインターなので、Exceptionが容易に発生する。
つまり、一通り出来上がっている振りをしているが、実は使い物にならないのだ。
そのため、jarをいくつもクラスパスに記述しないと、executeすらできない
ボロクソなものになってしまっている。
なぜこうなってしまったのかと云えば
java  xxxxx  -jar zzzzz.jar
と手軽に実行できるので、null pointer exceptionが起きたら・・・
足りない何かをくっ付けて
java  xxxxx  -jar zzzzz.jar -jar yyyyy.jar
とすれば済んでしまうので、
Javaコードの集合体はセキュリティ的には非常に危ない作りになっている。
java  xxxxx  -jar virus.jar -jar zzzzz.jar -jar yyyyy.jar
で簡単に乗っ取ることができる。
しかしサーバー内の話なのでOKということになっている。
ま、侵入されるなら、それ以前の出来事と云うところなのだろう。
 
 



Javaのインジェクションと節操のない初期化の山

簡単に書くと
ドコの
xxxDao   dao; /* 実は普通のクラスではなくinterfaceクラス */
なソースに
dao.selectXXXX(dto);
すれば、
簡単にNullPointerExceptionが起きて使えないが、
どこかでコッソり
dao = new xxxDaoBean();
してしまえば使える様になるたったそれだけのこと。
@EJB    ejb.jarのどこかのクラスのstatic Mainメソッド
とか
@Resource   ibatis.jarのどこかのクラスのstatic Mainメソッド
とか
アノテーションを書いておけば、誰かがやってくれる。
ハズ。
え?勝手にどうやって動くのか?

class   xxxx{

static {

/* スタティックの無名領域で初期化を無意識に恣意的に実行 */

initialize();

}

void  static initialize () {

/* 沢山の初期化処理 */

}

}

 で、いいじゃないですかね?
簡単でしょ?
※同じことはC++でも出来ます。
 
実は、環境に応じて、
dao = new batchDaoBean();
とか
dao = new onlineDaoBean();
とか
dao = new androidDaoBean();
とか
dao = new iosDaoBean();
とかに差し替えが効くところが良いのだが、
 
実際にはそんな使い方をすることは・・・
 
アリエナイ話。(爆
 
 
実にJavaは、何かのjarのMainが勝手に初期化するので、どんな動きになるか、判ったものではない。
当然のことだが、安易なインジェクションはソースレベルデバッグを困難にさせる。
strutsもそうだが、ソースが無いclassを跨いでワークフレームを作ることが多いからだ。
 
競合が起きて当たり前だし、上記の初期化処理に膨大な時間がかかるのも当然の話。
 
で、なんでそんなものを使うのか?
一つにはモジュールの差し替えがしやすい点があるものの。
 
そんなものはワークフレーム側の話で、それにぶら下がるクラスは普通に作ればいいはず。
でも、過去のインジェクションのデザインは、その上下関係が間違っていて、ワークフレームに作り込む方が
自動的にインタフェースじの変数にオブジェクトがインジェクションされることを前提にしている。
これは、ワークフレーム側がインジェクションの仕組みをカスタマイズする手法を勘違いして作ってしまったためだろう。
というかサンプルでサクっと作ったら、出回ってしまったと考えた方がいいだろう。
だって
/*  フレームワークのソース */

for(Class class :  all_class_list ) {

if(   class.isClass() ) {

for(Method method :  class.getMethodList() ) {

if( method.class.isInterface ) {

if(method.value == null) {

Object object = classMap(method.getClassName());

if( object != null ) {

method.value = object.getInstance();

}

}

}

}

}

}
な感じでnullにオブジェクトを挟んでくれたら楽そうに思える。
でも、その実態は・・・
 
interface  xxx = new XxxBean();
XXX.method()

@xxxInjection
interface  xxx;
XXX.method();
と書いて、全ソースのインジェクションを巡回する長~い初期化に時間を費やすことになり、
デバッグも面倒なので、
何も得るものはない。
ま、失敗なのだが、駄作であれ、悪貨であれ、出回ってしまったものが勝ちな世の中。
強いて云えば、
自分で作るつもりが無い部分をinterfaceとしてコードし、
その実装を外注に出せばいいだけだが
interfaceをclassに書き換えらる。(自分のコードを書き換えられるのが嫌)なら、
先のEJB手法が必要だ。
もっとも、
java   -jar 自分のソース.jar   -jar interface.jar

java   -jar 自分のソース.jar   -jar interfaceの処理を実装したクラス.jar
で実行すれば済む話でしかないのがEJBだ。
もちろん、自分のソース.jar にinterfaceの処理を実装したクラス.jarを使ってコンパイルしておかないとうまく動かない気がする。
ので、やっぱりEJBがいい。と思ってしまうのだろう。
だが、そんなEJBの動作テストはどうやるのか?
実装.jarができるまで放置しておくのか?
その辺の考慮がごっそりと抜け落ちているのが
やはりJavaerの幼さなのだろう。
 
でも、世の中どんどん変なものが残っていくのも仕方がないことだよね。(大笑 




top