そこで今回は、制御をオブジェクトを使って置き換えることで、これらの問題を解決していくことにする。
サンプル・プログラムの実行例
サンプル・プログラム
数字の正規化
- 半角数字 (例)12345678
- 半角数字カンマ区切り (例)12,345,678
- 全角数字 (例)12345678
- 全角数字カンマ区切り (例)12,345,678
- 漢数字 (例)一二三四五六七八
- 漢数字位取り (例)千二百三十四万五千六百七十八
- テキスト中から数字を抜き出す。
- 抜き出した数字を半角に統一する。
- 抜き出した数字に選択した正規化手法を適用する。
今回お伝えしたいのは、数字の正規化ではなく、3番目の正規化手法を選ぶ部分にある。
数字の正規化について興味がある方は、「PHPで漢数字を半角数字に変換する(整数版)」「PHPで半角数字を漢数字にする」を参考にしていただきたい。
読みやすいプログラム:制御をオブジェクトで置き換える
Webアプリケーションで、選択したラジオボタンによって作用や機能が変わるプログラムはよくある。今回紹介する方法を使うと、こうしたプログラムを作ったり拡張するのが容易になるだろう。
しかし、機能追加でDやEの場合が増えると、その分、条件分岐を増やさなければならず、テストケースが膨れあがる。かといって、すべてのテストケースを網羅しないと、バグを取りこぼす恐れがある。
ここで、「forEachループ - 5.1 配列とオブジェクト、for...in、forEachループ」で、配列やオブジェクト使って forループを読みやすくする方法を紹介したのを思い出して欲しい。これを応用することで、明示的な条件分岐を書かなくて済むようになる。
上図のように、ラジオボタン A と対応する関数 funcAが1組で1つのオブジェクトに、ラジオボタン B と対応する関数 funcB が1組で1つのオブジェクトに‥‥というオブジェクト配列を用意し、ラジオボタンの選択と関数がセットで動くようにしてやるのだ。
つまり、条件分岐をオブジェクトで置き換えるのが読みやすいプログラムということになる。
オブジェクトを使った関数定義
26: //正規化手法の一覧
27: let NormalizedFunctions = [];
28: /** 変数の構造
29: * [関数名]
30: * .label = ラベル(ラジオボタンに表示)
31: * .func = 関数本体
32: */
177: /**
178: * 半角英数記号文字を全角英数字に変換する.
179: * @param String str 半角文字列
180: * @return String 全角数字
181: */
182: NormalizedFunctions['toFullWidth'] = {
183: label : '全角',
184: func : function (str) {
185: const REG_TARGET = /[!-~]/g;
186:
187: return str.replace(REG_TARGET, function(ss) {
188: return String.fromCharCode(ss.charCodeAt(0) + 0xFEE0);
189: });
190: }};
配列 NormalizedFunctions への代入はやや複雑だが、こうすることで、ラジオボタンの選択と関数をパッケージング化することができる。複雑といっても定型化されており、他のラジオボタンと関数のセットも同様に定義・代入すればよい。
306: /**
307: * 元のテキストの中の数字を正規化して変換後テキストに表示する.
308: * @param なし
309: * @return なし
310: */
311: function dispNormalizeNumbers() {
312: func = getSelectedValue('func');
313:
314: let sour = document.getElementById('sour').value;
315: document.getElementById('dest').value = normalizeNumbers(sour, func);
316: }
このように制御をオブジェクトに置き換えたことで、正規化手法(=オブジェクト)を追加したときは、追加したオブジェクトの単体テストだけ行えば十分である。
コラム:オブジェクト指向とダイナブック
「1.2 画面にメッセージを表示する」のコラムで触れたように、本連載の構成は『プログラミング言語C』を参考にしている関係で、条件分岐などの制御構造を先に説明した。だが、ここでつまずいた方が何人かいるのではないだろうか。また、関数型プログラミングに慣れている方は、まだ初心者だった時代を思い出してほしい。
じつは、日常生活で制御構造を頭に思い浮かべるシーンは少ない。むしろ、上図のようなオブジェクトで行動を決めることが多いのではないだろうか。このため、制御構造でつまずいてしまう人が出るのは致し方ないと言えよう。
1970年代後半、ゼロックス社のパロアルト研究所(PARC)でアラン・ケイらが中心となってオブジェクト指向の研究が進められた。アラン・ケイは、紙の上で鉛筆を持って作業する作業を、そのままコンピュータ上で実現できるダイナブックを目指し、写真のミニコンピュータ Alto と、その上で動作するオブジェクト指向型プログラミング言語 SmallTalk を開発した。マウスやウィンドウシステムを使った先進的なGUIは、Macintosh に搭載され成功を収めた。また、紙のように持ち運んで作業ができるという部分は、東芝のノートPC「ダイナブック」に受け継がれた。
ラジオボタンの構造を取り込み、関数をメソッドにしたクラスを設計することで、さらにオブジェクト指向の度合いが高まる。
さらに、ラジオボタンだけでなく、「何かを選んだら、何かのメソッドを実行する」という基本構造を抽象クラスで定義し、それを継承して具体的なUIとメソッドを備えた具象クラスを書いてみよう。JavaScriptでは明示的に抽象クラスを宣言することはできないが(TypeScriptにはabstract修飾子が用意されている)、一般的なクラスで定義することになる。
これまで学んできたことから、選択されたラジオボタンの値を取得し、「3.1 if~else文」や「3.2 switch~case文」を使って対応する関数に制御を渡すというプログラムを作ることができるだろう。