3秒でわかる
ひとつの部品にはひとつの関心事だけを持たせる設計の考え方。変更したい理由ごとにコードを分けておくと、直す範囲が読まなくても分かるようになります。
もう少し詳しく
どういうものか
責務分離(関心の分離)は、ひとつの関数・クラス・モジュールが引き受ける仕事を、ひとつの関心事だけに絞る設計原則です。ここでいう関心事とは「何を計算するか」「どこからデータを取るか」「どう画面に出すか」「どんな形式で保存するか」といった、変更したくなる理由の単位を指します。
判断の基準は行数ではありません。その部品を書き換えたくなる理由が二つ以上あるなら、二つに分ける合図です。
なぜ必要か
混ざったままだと、修正の影響範囲が読み切れなくなります。画面の見た目を少し変えたいだけなのに、同じ関数に計算と保存処理が同居していると、売上の数字が変わっていないことまで確認しなければなりません。テストも書きづらくなります。計算だけを試したいのに、ブラウザや DB を用意しないと関数を呼べないからです。
具体例
取得と計算と表示が混ざった関数を分けます。
// 分ける前 取得・集計・DOM 操作が 1 つの関数に同居している
async function showTotal(userId) {
const res = await fetch(`/api/orders?user=${userId}`);
const orders = await res.json();
let total = 0;
for (const o of orders) total += o.price * o.count;
document.getElementById("total").textContent = `${total} 円`;
}
// 分けたあと
const fetchOrders = (userId) =>
fetch(`/api/orders?user=${userId}`).then((r) => r.json());
const calcTotal = (orders) =>
orders.reduce((sum, o) => sum + o.price * o.count, 0);
function renderTotal(el, total) {
el.textContent = `${total} 円`;
}分けたあとの calcTotal は、ブラウザも通信も無しでテストできます。税込計算に変えるときに読むのもこの関数だけです。
つまずきやすいところ
分ければ分けるほど良いと考えて、1 行の関数を大量に作ってしまう例がよくあります。ファイルを 5 つ開かないと処理の流れが追えないなら、それは分けすぎです。一緒に変更されるものは一緒に置く、という反対向きの力も同時に働いていると考えてください。
もうひとつは、ファイルを分けただけで満足してしまう場合です。別ファイルにしても、片方が相手の内部構造を細かく知っていて、片方を直すと必ずもう片方も直すことになるなら、関心事は分かれていません。
覚え方
「変更したい理由が違うものは、置き場所も分ける」と読み替えると判断できます。