1つのクラス・モジュール・関数を変更する理由は1つ以上存在してはならない。
- いろいろなものをモックしないといけないのでテストしづらくなる
- 1つ修正したときに周辺確認がやたら多くなり工数が増える
とあるシステムで製品のリストをCSVファイルで管理しており、 そこからいま販売中の製品だけを出力する社内向けスクリプトを書いた。
// いま販売している製品のリストをTSVファイルで出力する
function generateAvailableProductList(companyName: string): void {
// filePathからテキストデータを読み出す
const text: string = file.readFileSync(`../products/${companyName}.csv`);
// CSVとしてパース
const header = ["no", "name", "available", "count"];
const csv: CSV = CsvParse.parse(text, { header });
let lines = "";
// 読みだした結果を使ってTSVファイルを作る
for (const row of csv.rows) {
if (row["available"] === "1") continue;
const line = row["name"] + "\t" + row["count"] + "\n";
lines += line;
}
file.writeFileSync(`${companyName}.tsv`, lines);
}
いろいろな変更理由でこの関数を修正したくなる。
- インフラチームから連絡: クラウド移行したのでファイルをローカルではなくサーバから取得して。
- システムチームから連絡: CSVファイルの列の順序が変更されたよ or カラム名が変わったよ。
- ユーザーから要望: UTF-8のTSVファイルじゃExcelで開けないからCSVで出力してよ。
// 製品
class Product {
no: number;
name: string;
available: boolean;
count: number;
}
// 製品情報リストをCSVファイルから読み出す
function readProductListCsv(csvText: string): Product[] {
const header = ["no", "name", "status", "count"];
const csv: CSV = CsvParse.parse(csvText, { header });
return csv.rows.map(row => {
const no = row["no"];
const name = row["name"];
const available = row["available"] === "1";
return { no, name, available };
});
}
// 製品情報リストをロードする
function loadProductList(companyName: string): Product[] {
const csvText = file.readFileSync(`products/${companyName}.csv`);
return readProductListCsv(csvText);
}
// いま販売している製品のリストをTSVファイルで出力する
function generateAvailableProductList(companyName: string): void {
const products = loadProductList(companyName);
let lines = "";
// 読みだした結果を使ってTSVファイルを作る
for (const product of products) {
if (!product.available) continue;
const line = product.name + "\t" + product.count + "\n";
lines += line;
}
// 書き込み
file.writeFileSync(`${companyName}.tsv`, lines);
}
- インフラチームから連絡: クラウド移行したのでファイルをローカルではなくAPIサーバから取得して。
loadProductList
を修正
- システムチームから連絡: CSVファイルの列の順序が変更されたよ or カラム名が変わったよ。
readProductListCsv
を修正
- ユーザーから要望: UTF-8のTSVファイルじゃExcelで開けないからCSVで出力してよ。
generateAvailableProductList
を修正
- これで本当にSRPにしたがっているか?
- これが最善か?
.
.
.
.
.
.
.
.
.
.
.
.
答え: 状況に依る。
- 製品数が増えてメモリ上に乗り切らなくなったらloadProductListは単純な配列を返せなくなる。
- システムの構成がもうFIXしているのを知っている場合、このコードはムダに長い。
- 変更の理由が変更たるのは、実際に変更の理由が生じた場合だけである。
- 変更の兆候がないのに単一責任の原則を適用するのは、やめたほうがいい。