ウィリアムのいたずらの、まちあるき、たべあるき

ウィリアムのいたずらが、街歩き、食べ物、音楽等の個人的見解を主に書くブログです(たま~にコンピューター関係も)

スパゲティなプログラムを分解してイベントにして、簡単にする方法1・・簡単な例

2006-08-04 17:35:10 | Weblog

 前に、たしか、基質特異性の話を書こうとした気がします。

 複雑なプログラム(まあ、スパゲティになっちゃうようなやつ)を、簡単にするのに、細かくわけて、それを、人間がやっている酵素の基質特異性みたいなことすると、うまくいくよ。。
 ってかいて、そのあと、細かく分けての話をずーっとして(産能大記号)、結局、基質特異性のほうのはなしをしてなかったんで、きょうは、そっちのほうをかきますね。




 酵素の基質特異性っていうのは、ある特定のものにしか、反応しないという性質。
 これがあると、いろんなものがまじっていても、ある特定のものだけ分解する。
 その分解されたやつが、また、特定のものにだけ反応して、分解する。。。と
 つづいていくやつ。

 つまり、これを応用すると、

 いろいろ複雑につづいているプログラムも、
  ステータスをふって、そのステータスのときだけ動き、
  その働きが終わったら、次のステータスにする。。
 っていうふうにしていくと、
 (ステータスが基質にあたる)

 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文の入れ子の}がたらなくて。。。なんていうミスは防げます。




 今日は、同時並列処理がなかったのでかんたんでしたけど、
 そのような、スレッドで、同時並列処理させる場合とかについては、また今度
 かきたいとおもってます。


この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« 中国向けPOPによるメール取得... | トップ | 「リネージュガール、コスプ... »
最新の画像もっと見る

Weblog」カテゴリの最新記事