前に、たしか、基質特異性の話を書こうとした気がします。
複雑なプログラム(まあ、スパゲティになっちゃうようなやつ)を、簡単にするのに、細かくわけて、それを、人間がやっている酵素の基質特異性みたいなことすると、うまくいくよ。。
ってかいて、そのあと、細かく分けての話をずーっとして(産能大記号)、結局、基質特異性のほうのはなしをしてなかったんで、きょうは、そっちのほうをかきますね。
酵素の基質特異性っていうのは、ある特定のものにしか、反応しないという性質。
これがあると、いろんなものがまじっていても、ある特定のものだけ分解する。
その分解されたやつが、また、特定のものにだけ反応して、分解する。。。と
つづいていくやつ。
つまり、これを応用すると、
いろいろ複雑につづいているプログラムも、
ステータスをふって、そのステータスのときだけ動き、
その働きが終わったら、次のステータスにする。。
っていうふうにしていくと、
(ステータスが基質にあたる)
switchで、ステータスによってディスパッチするコントローラーをつくって、
あとは、状態遷移におとしこめるってこと。。。
・・・なにいってるか、自分でもわかんなくなってきたので、
例を挙げます。
■例
以下のようなフローがあります。
このぐらいだったらIF文で書いてもわかるけど、もっと複雑になると
分けわかんなくなって、スパゲティになってしまいます。
そこで。。。
■手順
1.まず、上記のフローで、入力が1つ、出力が1つ(1本の線しかない)ところは、まとめて、
1モジュールとします。
2.そして、出力のところに、番号を振ります。
そうすると、こんな図になります。
この図をプログラムします。
■ソース
ソースは、こんな感じになります。
public ststic void main(String[] args) { // 引数を設定している=ここは、本題ではない HashMap map = new HashMap(); if ( map == null ) { // エラー sts = 9; } else { // 引数はハッシュマップにいてておくと、 // 関数の取り外しに便利 for(int i = 0 ; i < args.length ; i ++ ) { map.put("para"+i,args[i]); } // ステータスの初期化 sts = 0; } while(sts < 8 ) { switch(sts) { case 0: // 一番初め:処理1 sts = syori_1(map); break; case 1: // 条件1 sts =zyoken_1(map); break; case 2: // 処理2 sts = syori_2(map); break; case 3: // 処理4 sts = syori_4(map); break; case 4: // 処理3 sts = syori_3(map); break; case 5: // 処理4 sts = syori_4(map); break; case 6: // 処理5 sts = syori_5(map); break; case 7: // 処理5 sts = syori_5(map); break; } } if ( sts > 8 ) { System.out.println("Error"); } } /*============================================ * 処理1<p> *============================================*/ public int syori_1(HashMap map) { // ここに処理1のときの処理を書く // えらーのときreturn 9; // 処理終了時のステータスをセット return 1; } /*============================================ * 条件1<p> *============================================*/ public int syori_1(HashMap map) { if ( map == null ) return 9; // エラー String para2 = (String)map.get("para2"); // 条件を判断して、 // 分岐先のステータスをセット if ( para2 == null ) { return 3; } else if ( para2.equals("2") == true ) { return 2 } return 4; } //==============以下の処理は省略================// |
(上記 < > ¥ は、本当は、半角です)
上図の番号をcase文にかき、そのcase文の下に、起動する処理を書きます。
で、結果としてsts(ステータス)をもらっています。
こんかいのような簡単なケースではこれでもOKですが、次回以降に説明する、
並列処理などを考える場合は、このような形でなく、終了したってことを、
ハッシュマップなり、リストなりにいれます。
処理の場合は、うまくいったら、終了の(上図の)番号を、エラーのときはエラーステータス
(ここでは9)を返します。
条件のときは、それぞれの条件の(上図の)番号を、エラーのときはエラーステータス
(ここでは9)を返します。
最後の処理になると、while文がfalseになり、抜けます。
また、エラーのときもfalse担って抜けるようにします。
■このようにするメリット
こうすると、イベントと処理っていうことになるので、状態遷移図で管理できるようになり、1つ1つのプログラムの取り外しや修正も(プログラムが局所化され、重複の場合、同じ処理を使うので、検索しやすくなって)見やすくなります。
すくなくても、if文の入れ子の}がたらなくて。。。なんていうミスは防げます。
今日は、同時並列処理がなかったのでかんたんでしたけど、
そのような、スレッドで、同時並列処理させる場合とかについては、また今度
かきたいとおもってます。