分岐

「条件分岐はない方がいい。」

開発を手伝ってくれている友人に、Web で使うディスクロージャー トライアングルの実装をお願いした。Web アプリに詳しい訳ではない彼が、苦労して試行錯誤の上で作ってくれたのがこれだ。

// キャッシュ
img_expanded = "expanded.gif";
img_collapsed="collapsed.gif";
new Image().src = img_expanded;
new Image().src = img_collapsed;

// 展開
function expand(obj) {
	document.getElementById(obj+"i").src = img_expanded;	// img タグ src 属性の変更
	document.getElementById(obj).className = 'expanded';	// style タグ display 属性の変更
}

// 圧縮
function collapse(obj) {
	document.getElementById(obj+"i").src = img_collapsed;	// img タグ src 属性の変更
	document.getElementById(obj).className = 'collapsed';	// style タグ display 属性の変更
}

// 展開・圧縮の切り替え
function dtSwitch(obj) {

	// オブジェクトが取得できるかどうか
	if (document.getElementById && document.getElementById(obj) !=  null) {
		nodeState = document.getElementById(obj).className;
	}
	
	if (nodeState == 'collapsed') {
		expand(obj);
	} else {
		collapse(obj);
	}
}

スタイルシートの属性を切り替えて、表示、非表示をコントロールする仕組みとなっている。十分に機能しているし、通常であればこれで受け入れているところなのだが、二つの関数 expand と collapse がほとんど同じような処理となっていて冗長に感じたため、書き直してもらうことにした。

expand と collapse の中をよく見ると、式の左辺が同じで右辺が異なるだけなので、右辺をパラメータとして受け取るようにすれば一つの関数で済むようになる。実は右辺の値は状態に依存した静的な情報 (実行時ではなく、開発時に決定している) なので、ハッシュに入れて状態をキーにして引っ張れるようにすれば、パラメーターで受け取る必要もなくなる。そんなサンプルを Ruby で書いて渡して、書き直してもらったのがこれ。

// 状態管理情報用クラス
function state(_img, _className) {
	this.img = _img;
	this.className = _className;
	new Image().src = _img;	// 画像をキャッシュ
}

// 状態管理情報の定義
var stateMap = new Object();
stateMap["expanded"] = new state("collapsed.gif", "collapsed");
stateMap["collapsed"] = new state("expanded.gif", "expanded");

// 展開/巻き上げの切り替え
function toggle(blockID, imageID) {
    // 準備
    block = document.getElementsByName(blockID)[0];
    image = document.getElementsByName(imageID)[0];
    stateObj = stateMap[block.className];

    // 処理
    block.className = stateObj.className; // 表示/非表示切り替え
    image.src = stateObj.img;    // 画像の切り替え
}

もう一つ修正してもらったのが、obj+"i" の除去だ。これは暗黙のネーミングルールに依存しているのを嫌ったもので、JavaScriptCSS 以外の知識がなければ読めないコードは、できるだけ避けたいからだ。

最終的に if 文がなくなり、上から順にやることを並べただけの単純なコードになったし、意図のはっきりした可読性の高いコードになった。細かい修正ではあるが、巨大なシステムの見通しの良さを維持するためには、こういったことの積み重ねが必要だ。