Firebaseの技術情報サイト

Firebaseの技術情報サイト

Firebase活用の為の技術情報サイトです

改良版足し算プログラム

改良版足し算プログラム

前回は、入力データのチェックを工夫することで、データを処理する前に想定外のデータの入力を制限するユーザーインターフェースの設計について紹介しました。この記事では、そのコンセプトを使って、実際に足し算をするプログラムにしてみました。今回のポイントは、ユーザーインターフェースとデータ処理を分けるという点に注目してみました。プログラムの設計の際には、この二つの境界をきちんと設定する事が大切です。

目次
データの処理は?
残りのプログラムは?
ユーザーインターフェースとデータ処理を分ける理由
開発の分業も重要
まとめ

データの処理は?

このプログラムは、入力された二つの整数を足して結果を表示するというシンプルなプログラムです。 このプログラムのデータ処理部分は、実は二つの整数の足し算をするだけです。

つまり、プログラムのデータ処理部分は以下の関数「add(a, b)」だけです。

function add(a, b) {
  return a + b;
}

処理自体は、二つの整数「a」と「b」を受け取って、この二つの整数を足し算した結果を返すというシンプルなものです。

残りのプログラムは?

このプログラムのデータ処理部分は、至ってシンプルです。 では、残りのプログラムは何かというと、これがユーザーインターフェースになります。

<!DOCTYPE html>
<html>
  <head>
    <title>Add Program</title>
  </head>
  <body>
    <div>
      <input id="opeland0" type="text" placeholder="Please input integer" />
      <label>+</label>
      <input id="opeland1" type="text" placeholder="Please input integer" />
      <label>=</label>
      <input id="result" type="text" readonly />
      <button onclick="calculateEvent()">Calculate</button>
      <button onclick="clearFieldsEvent()">Clear fields</button>
    </div>
  </body>
</html>
<script>
  // Input fields
  const inputField0 = document.getElementById("opeland0");
  const inputField1 = document.getElementById("opeland1");
  // Output fields
  const resultField = document.getElementById("result");
  // Current value
  let ope0Value = "";
  let ope1Value = "";
  // Adds event listener
  inputField0.addEventListener("keyup", (event) => keyupEvent(event));
  inputField1.addEventListener("keyup", (event) => keyupEvent(event));
  /** Calculate event handler */
  function calculateEvent() {
    // Clears the output field
    resultField.value = "";
    const ope0 = parseInt(inputField0.value);
    const ope1 = parseInt(inputField1.value);
    if (isNaN(ope0) || isNaN(ope1)) {
      alert("数値が入力されていません!");
    } else {
      const result = add(ope0, ope1);
      resultField.value = result;
    }
  }
  /** Clear fields event handler */
  function clearFieldsEvent() {
    inputField0.value = "";
    inputField1.value = "";
    resultField.value = "";
  }

  /** Key down event hander
   * @param e Key down event object
   */
  function keyupEvent(e) {
    const currentChar = String.fromCharCode(e.keyCode);
    const id = e.target.id;
    const value = e.target.value;
    if (currentChar === "\b" || !isNaN(currentChar)) {
      if (id === "opeland0") {
        ope0Value = value;
      } else {
        ope1Value = value;
      }
    }
    inputField0.value = ope0Value;
    inputField1.value = ope1Value;
    resultField.value = "";
  }

  // 意図的に「function add(a, b)」を抜いてあります
</script>

上の例では、意図的に「function add(a, b)」を抜いてあります。 これが、ユーザーインターフェースの部分です。

ユーザーインターフェースは、大きく二つの部分から構成されています。

  • データを入力するためのフォーム(HTML で記述)
  • 入力フォームをサポートするプログラム(Javascript で記述)

データを入力するフォームは、Javascript では記述できないので、HTML を利用して作成します。 さらに、入力フォームをサポートするためのプログラムを Jvascript で書いています。

入力フォームをサポートするプログラムがやっていることは以下の通りです。

  • イベントの検出と処理
  • 入力するデータの制限(整数のみ有効にする)
  • データ処理の呼び出し

この入力フォームで発生するイベントは、二つのタイプがあります

  • 入力フィールのデータをキー入力するイベント(keyupEvent)
  • ボタンのクリック(計算のためと、フィールドをクリアするための処理を呼び出すためのイベント)

計算に利用するデータがタイプされた場合、入力する整数の値が変わる事になるので、結果を表示するフィールドの値がある場合その結果は無効になります。 したがって、データが変更された場合には、結果を自動でクリアするようにしています。

ユーザーインターフェースとデータ処理を分ける理由

ところで、今回の記事では、実際の足し算をするプログラムの実装例を紹介する以外に、ユーザーインターフェースとデータ処理を分けるという例を紹介するという別の目的があります。 これには、理由があって、ユーザーインターフェースとデータ処理を分けるとプログラムの変更や管理をするのに都合が良くなり場合が多くなるからです。

この例では、データ処理は、単純に二つの整数の足し算を計算するだけなので、ユーザーインターフェースとデータ処理を明確に分けるメリットは少なくなります。 しかし、通常のプログラムでは、データの処理はもっと複雑になる場合が殆どです。その場合、ユーザーインターフェースとデータ処理を分けておいた方が良い点があります。

一番のメリットは、ユーザーインターフェースとデータ処理を別々に管理する事が可能になる点にあります。

ユーザーインターフェースは利用者が直接入力や操作を行うので、この設計でプログラムの使い勝手が変わってきます。一方でデータ処理は、今回の足し算のプログラムではシンプルですが、複雑な処理をする場合には、プログラムの書き方で処理の性能(処理時間など)が大きく変わる場合も出てきます。そう考えた場合、これらを別々にしておいた方が、必要な部分の修正をやりやすくなるという利点があります。

また、プログラムに問題がある場合にも、問題の場所を絞る意味でも、別々になっている方がデバッグをやりやすい場合が多くなります。入力されたデータを準備する段階で問題があるのか、実際のデータ処理に問題があるのかを切り分けることで、デバッグの範囲を限定できる場合が多くなります。

もう一つは、プログラムの再利用という点でも、ユーザーインターフェースとデータ処理を分けるとより再利用しやすくなります。 例えば、今回の例では、足し算をするプログラムですが、これを引き算をするプログラムに変更したり、あるいは、足し算、引き算、掛け算、割り算全てをできるように変更する際も、ユーザーインターフェースとデータ処理部分を分けておくと変更や機能の追加もやりやすくなります。

開発の分業も重要

ここまでは、プログラムを一人で開発する場合を想定してきました。 しかし、実際にはプログラムの開発は複数の開発者で分担をして開発するケースもたくさんあります。 特に、企業などで開発する場合には、そうしたケースは当然多くなります。

実際に、今回の例を見ればわかりますが、ユーザーインターフェースとデータの処理では、プログラムのスタイルや書き方も結構変わってきます。

ユーザーインターフェースでは、フォームの部品の配置や全体の構成次第で使い勝手は大きく変わる場合も多くなります。 一方で、データ処理の方は、データの扱い方や処理の手順で、データ処理にかかる時間や結果の精度なども変わってきます。 それぞれで、ある程度の専門的な知識や経験が要求される事になります。こうした場合、それぞれの分野で得意な人がプログラムを担当した方が、より良いプログラム(アプリ)を開発できることになります。

そうした意味で、プログラムの開発の際にユーザーインターフェースとデータ処理を意識してプログラムを書くと、そうした開発にも対応しやすくなります。

まとめ

この記事では、ユーザーインターフェースの改善をして、足し算のプログラムをより使いやすくまとめると同時に、ユーザーインターフェースとデータ処理を意識することを紹介してきました。

実際のプログラムでは、ユーザーインターフェースの中でも、いくつかの部分に分けることも多くなりますし、データ処理もさらに細分化した部分に分ける場合が多くなります。プログラム開発のポイントは、実はいかに、全体の機能を別々のプログラムに分けて構成するかを考えることがとても重要です。

こうした、プログラムの分割を意識することで、より見通しがよく、分業やデバッグをやりやすいプログラムにすることが可能になります。加えて、プログラムを上手く分割することで、将来的にプログラムの再利用や変更を簡単にすることも可能になります。

まずは、シンプルなプログラムでも、こうしたプログラムの分割を意識することで、ワンランク上の技術者になることができます!