JavaScript | ゼロからはじめるプログラミング、30日で基礎を学ぶJavaScript:ミニWebアプリ開発 - Day24:アプリ設計

JavaScript JavaScript
スポンサーリンク

Day24 後半のゴール

前半で「入力・処理・出力」という軸を使うと、アプリの設計がシンプルに考えられることを見ました。
後半では、もう少し“アプリっぽい”例を使って、

入力・処理・出力をどう分解するか
関数分割とどう組み合わせるか
設計からコードに落とす流れをどう踏むか

を、実戦レベルで体に染み込ませていきます。


例題アプリ:シンプルなToDoリストを設計する

まずは「言葉」で仕様を書く

作るものは「シンプルなToDoリスト」です。
機能は最小限に絞ります。

やりたいことを1行で入力する
「追加」ボタンを押すと、下にタスクが増える
ページをリロードすると消えてOK(保存は一旦考えない)

これを「入力・処理・出力」に分けて言葉にします。

入力
タスクの内容(テキスト)
追加のタイミング(ボタンを押したとき)

処理
入力されたテキストを受け取る
空でないかチェックする
タスクの一覧に追加する

出力
タスク一覧を画面に表示する

このレベルまで言葉で整理できていれば、
HTML と JavaScriptに落とすときに迷いがほとんどなくなります。


入力・出力を先に形にする

HTMLに「入力」と「出力」の場所を用意する

さっきのToDoリストを、まずは画面の構造にします。

<input id="todoInput" type="text" placeholder="やることを入力">
<button id="addButton">追加</button>

<h2>タスク一覧</h2>
<div id="todoList"></div>

ここで決めているのは、

入力は input 要素(todoInput)
追加のトリガーはボタン(addButton)
出力先は div(todoList)

ということです。

「入力」と「出力」の場所が決まると、
JavaScript側で「どこから値を取り、どこに結果を出すか」がはっきりします。


処理を関数として設計する

「処理」をそのまま関数名にする

ToDoリストの処理は、こう言い換えられます。

タスクを追加する
タスク一覧を表示する

これをそのまま関数名にしてしまいます。

addTodo
renderTodos

という2つの関数を用意するイメージです。

JavaScript側の骨組みはこうなります。

const todoInput = document.getElementById("todoInput");
const addButton = document.getElementById("addButton");
const todoList = document.getElementById("todoList");

const todos = [];

function renderTodos() {
  // ここで出力(表示)を担当
}

function addTodo(text) {
  // ここで処理(追加)を担当
}

addButton.addEventListener("click", () => {
  // ここで入力を受け取る
});
JavaScript

ここまでで、

入力 → イベントハンドラ
処理 → addTodo
出力 → renderTodos

という役割分担が見えてきます。


ToDoリストをコードで完成させる

処理と出力を実装する

まずは「処理」から書きます。

function addTodo(text) {
  todos.push(text);
}
JavaScript

次に「出力」を書きます。

function renderTodos() {
  todoList.textContent = "";

  todos.forEach((text) => {
    const p = document.createElement("p");
    p.textContent = text;
    todoList.appendChild(p);
  });
}
JavaScript

最後に「入力」を扱うイベントハンドラを実装します。

addButton.addEventListener("click", () => {
  const text = todoInput.value.trim();

  if (text === "") {
    return;
  }

  addTodo(text);
  renderTodos();
  todoInput.value = "";
});
JavaScript

ここでの流れは、完全に「入力・処理・出力」に沿っています。

入力 → input から値を取得し、空チェック
処理 → addTodo で配列に追加
出力 → renderTodos で画面に反映

この「流れの見えやすさ」が、設計を意識する最大のメリットです。


設計の視点をもう一段深くする

「入力・処理・出力」をさらに分解して考える

同じToDoアプリでも、もう少しだけ設計を細かく見ることができます。

入力
テキストの取得
入力値のバリデーション(空チェック)

処理
配列への追加
(将来的には削除・編集もここに増える)

出力
一覧の再描画
見た目の調整(クラス付与など)

このように、「入力・処理・出力」をさらに小さな役割に分けていくと、
関数分割のヒントが見えてきます。

例えば、バリデーションを関数にすることもできます。

function validateTodo(text) {
  if (text === "") {
    return "タスクを入力してください。";
  }
  return null;
}
JavaScript

イベントハンドラはこう書き換えられます。

addButton.addEventListener("click", () => {
  const text = todoInput.value.trim();
  const error = validateTodo(text);

  if (error !== null) {
    console.log(error);
    return;
  }

  addTodo(text);
  renderTodos();
  todoInput.value = "";
});
JavaScript

ここまで来ると、

入力 → 値の取得+バリデーション
処理 → addTodo
出力 → renderTodos

という構造が、よりはっきり見えてきます。


もう一つの例:判定系アプリで設計を練習する

例題:年齢でメッセージを変えるアプリ

次のようなアプリを考えます。

年齢を入力する
「判定」ボタンを押す
20歳以上なら「成人です」、未満なら「未成年です」と表示する

これを「入力・処理・出力」に分けます。

入力
年齢(数値)

処理
数値に変換する
20以上かどうかを判定する

出力
結果メッセージを画面に表示する

ここから、関数の候補が見えてきます。

判定処理 → judgeAge
出力処理 → showResult

判定アプリのコード

HTML はシンプルです。

<input id="ageInput" type="number" placeholder="年齢">
<button id="judgeButton">判定</button>
<p id="message"></p>

JavaScript はこう書けます。

const ageInput = document.getElementById("ageInput");
const judgeButton = document.getElementById("judgeButton");
const message = document.getElementById("message");

function judgeAge(age) {
  if (age >= 20) {
    return "成人です";
  }
  return "未成年です";
}

function showResult(text) {
  message.textContent = text;
}

judgeButton.addEventListener("click", () => {
  const age = Number(ageInput.value);
  const resultText = judgeAge(age);
  showResult(resultText);
});
JavaScript

ここでも、

入力 → イベントハンドラで age を取得
処理 → judgeAge
出力 → showResult

という構造になっています。


設計のチェックポイント

「このコード、どこが入力でどこが出力か」を説明できるか

設計がうまくできているかどうかは、
自分にこう問いかけるとチェックできます。

どこでユーザーの入力を受け取っている?
どこでアプリの「中身の状態」を変えている?
どこでユーザーに結果を見せている?

それぞれに対して、

この部分が入力
この関数が処理
この関数(または行)が出力

と説明できるなら、設計はかなり良い状態です。

逆に、

入力・処理・出力がごちゃごちゃに混ざっている
イベントハンドラの中に全部詰め込んでいる
どこを直せばいいか一瞬で分からない

という状態なら、
「入力・処理・出力」に分けて書き直す価値があります。


Day24 後半のまとめ

後半でやったことを整理すると、こうなります。

ToDoリストを「入力・処理・出力」で設計した
入力 → input とボタン
処理 → 配列への追加(addTodo)
出力 → 一覧の描画(renderTodos)
判定系アプリでも同じ考え方を使った
入力・処理・出力を関数分割と組み合わせて整理した
「このコードの入力・処理・出力はどこか?」と説明できるかを設計のチェックに使う

ここまで来ると、
新しいアプリのアイデアが出てきたときに、
いきなりコードではなく「入力・処理・出力」でスケッチできるようになります。

それができる人は、コードが長くなっても迷子になりにくい。
Day25 以降は、この設計力を土台にして、
実際のミニWebアプリをどんどん形にしていくフェーズに入っていきます。

タイトルとURLをコピーしました