変奏現実

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

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

2014年3月31日

Bean Inistialize

JavaでパラメータにBeanを使うことが多い。
理由はFind Bugsなどでパラメータが大杉だタコとテントウムシに指摘されるからだが・・・
中には
/**
* parametersNil
*/
class parametersNil {
/* empty */
}
という強者も、メソッドのパラメータが必須なツールを使う場合には必修である。
特にEJBの様なinterfaceやRedaer・Writerの様なパイプラインではBeanを使わない手は無い。
ただ、引き回している内に
Beanの中身に誰も関心を持たなくなり、
・誰かがパラメータをチェックしているだろうとかパラメータを使う奴がチェックするハズとか
・反動で1パスの度にゼンパラメータチェックとか
極端なことになりやすい。
さらにパイプラインの途中の処理がヒント情報(httpはTCPIP通信のプロトコルです など)を追加したいばかりに
parametersNil がめでたく、parameters1 になるのは良いとしても
parameters100をparameters101にするのは結構厄介だ。
そう、100個分のパラメータ・コピーをparameters101のコンストラクタに埋め込まないと厄介だからだ。
更にいつのまにかparameters100Α型(実は前段の処理が隠しプロパティが1つ追加した)になっていた場合、
Aの部分(前段の処理が追加した隠しプロパティ)が抜け落ちてしまう。このため、前段の処理の担当者は
Aの部分のパラメータ・コピーで埋める旅に出かける必要がある。
BeanUtils.copyPropertiesを使えば全てOKなんだけどね。

ConvertUtils.register(new IntegerConverter(null), Integer.class);
と設定してから使えばInteger(null)がnullのまま変換してくれるので、
ちょっと違った変換も可能。
というか、Strutsの中でもisNull判定(=設定なし)を使ってたらInteger(null)が0になって困った事態が発生したのだろう。
しかし、自前で頑張らず親のすねをかじる方針を立てれば、
最初の基底クラスに
void  XXbaseClass::Inistialize( XXbaseClass ) を実装しておけば
void XX::Inistialize(XX  object) {
// COPY ALL PROPERTIES
this.setter_baseProperty_1( object.getter_baseProperty_1() );
・・・
this.setter_baseProperty_N( object.getter_baseProperty_N() );

}

後の派生クラスは喜んでcopyLeft(my)を実装し、
void XX::Inistialize(XX  object) {
super.Inistialize(object);
/*
* 追加したプロパティだけコピー
*/
this.setter_1( object.getter_1() );
* ・・・
this.setter_N( object.getter_N() );

するハズだ。

そう、先導や誘導も時として重要なのである。
え?100個もプロパティがあったら大変だって?
そのBeanの Copy Constructer の中身を拝借すると
XX::XX( XX xx) {
   Inistialize(xx);
}
XX::Inistialize(XX xx) {
/*
* さっきまでXX::XX( XX xx)にあった処理
*/
}
で出来上がります。(大笑
でもこれってC++じゃ常套手段だったりするけどね。(大笑(大笑(大笑(大笑(大笑
そうつまりJavaの基底クラスを作ってる人って・・・ってことです。(大笑(大笑(大笑(大笑(大笑(大笑(大笑(大笑(大笑(大笑(大笑(大笑(大笑(大笑(大笑
もちろんレビュワーも


良いコピペと悪いコピペ

プログラムを作る時、
大抵はいくつかのパーツに分ける。
プロパティファイルを読み込むリーダーを作るなら
BinaryFileReader <- TextFileReader <- LineFileReader <- PropertyFileReader
な感じだろうか。
普通ならPropertyFileReaderに使うプロパティファイルをパラメータで指定し、
BinaryFileReader <- TextFileReader <- LineFileReader
の部分は何も変更が無く、大抵のファイルならそのまま流用ができる。
この場合の正統派なコピペは、
PropertyFileReader pfr1 = new PropertyFileReader(“xxxxxxx-1.property”);
PropertyFileReader pfr2 = new PropertyFileReader(“xxxxxxx-2.property”);
PropertyFileReader pfr3 = new PropertyFileReader(“xxxxxxx-3.property”);
となる。
ところが実際には・・・
String [] fileNameList = {
“xxxxxxx-1.property”
,”xxxxxxx-2.property”
,”xxxxxxx-3.property”
};
List <PropertyFileReader> pfrLst = new List <PropertyFileReader>();
for( propertyFileList in propertyFile) {
pfrLst.Add( new PropertyFileReader(“xxxxxxx-1.property”) );
}
の様に、やりたい事に比べて助長過ぎるソースが美しいとされるが、何もメリットは無いし、
static final int   PROPERTY_FILE_INDEX_1  =0;
static final int   PROPERTY_FILE_INDEX_2  =1;
static final int   PROPERTY_FILE_INDEX_3  =2;
pfrLst[PROPERTY_FILE_INDEX_1 ].get(PROPERTY_MEBMER_1);
pfrLst[PROPERTY_FILE_INDEX_2 ].get(PROPERTY_MEBMER_2);
pfrLst[PROPERTY_FILE_INDEX_3 ].get(PROPERTY_MEBMER_3);
のように面妖なConst 定数を使ってプロパティファイルにアクセスしなくてはならなくなり、また勢いソースの行は妙に長くなってしまう。
悪い例のレビュー前:  pfr1.get(“1”);
悪い例のレビュー後: pfrLst[PROPERTY_FILE_INDEX_1 ].get(PROPERTY_MEBMER_1);
つまり、やりたい事を理解せずにソースレビューだけするとたった3行のコピペが上の様な有様に至ってしまう。
更に、ファイル名をConstクラスに差し込んだり、あるいは・・・プロパティファイルに入れてみたりすると、もう終わってる感じがする。
これはWEBでよく見かける見栄えの良いコーディングとは

無駄の塊

でしかないことを意味する。
では、
PropertyFileReader pfr1 = new PropertyFileReader(“xxxxxxx-1.property”);
という1文は見栄えが悪いのかと云えば、そんなことは無い。
ただ、
PropertyFileReader pfr1 = new PropertyFileReader(“xxxxxxx-1.property”);
・・・(98行中略)・・・
PropertyFileReader pfr100 = new PropertyFileReader(“xxxxxxx-100.property”);
となれば何か方法は無いのか?と云いたくなるだけだ。
こうなると、先の無駄の塊がなんとなく見栄えが良く見えてくるから不思議である。
但し、100個もファイルを開いて何をするつもりなのか?という根本的な問題をまず考えるべきである。
その結果が、

100個ファイルを開いても大丈夫なことを確認したかっただけ

だったりすると、100行のコピペで十分な気がする。(大笑
ただ世の中には尋常ではないコピペが存在する。
JCLである。
古い話で恐縮だが、JCLに渡せるパラメータは1個のINT型だけだった古い時代。
Aファイルを読み、書式を変換し、Bファイルに書き出す。
のような単純なことでも
Aファイルが10個あれば
JCL00001
・・・
JCL00010
と違うプログラムを流さないといけなかった。
そう、この10個のプログラムで異なる部分は入力ファイル名と出力ファイル名だけである。
なせなら、C言語が出現する前にも文字列型変数はあったが、概ね固定長であった。
このためJCLのパラメータに文字列型変数を使える様にすると
main( char parameter[10] ) {
・・・
}
にするしかなく、とてもかっこが悪かった。
更に、文字列型のパラメータの数を増やしたりしたら
main( char parameters[5] [10] ) {
・・・
}
とかになっても、どうやって読めばいいのか直観的に判らないシロモノになってしまうからだ。
もっとも、JCLごとにパラメータの数が違うような仕組みは考えられなかったのだろう。
なんたって、1バイトのメモリは血の一滴。とても貴重だった時代なのだから・・・
 
もっとも、パラメータが1~10の場合にファイル名をIF文で振り分ければいいハズだが、ソースレベルデバッガどころがラインデバッガさえ使わせて貰えない時代。つまりVDTな画面とキーボードなんて高値の華だったころは、パ ンチカードな時代で、IF文を書くより、ファイル名の1行(カード1枚)を差し替える方が簡単で動作も確認しやすかったのだ。
ただ、その流れが現在も続いている(もちろん機能は色々拡張されている)のはかなりウザいなぁと思う次第だ。
※もちろん、MMORPGのマクロはJCL系ではある。
しかしJCLを使うのが金稼ぎに来たプログラマなのに対して、
マクロを使うのはお金を払ってくれるユーザであるため、
使いにくいとは云われつつも、JCLの数億倍もパラメータが使いやす。
JCLに似ているが全くの別物である。




top