コード品質 レッスン4
コードスメルの見つけ方
長すぎるメソッドや重複コードなど、設計上の問題を示唆するコードスメルの種類と見つけ方を学ぶ
コードスメルとは
コードスメル(code smell)とは、 それ自体がバグではないものの、設計上の問題を抱えている可能性を示す「兆候」のことです。 「臭い」がするからといって必ず腐っているとは限りませんが、確認する価値のあるサインです。
代表的なコードスメル
長すぎるメソッド(Long Method)
1つの関数が何十行、何百行にもなり、複数の責任を抱えている状態。 スクロールしないと全体が把握できない関数は分割の候補です。
重複コード(Duplicated Code)
同じ、あるいはよく似たロジックが複数箇所に存在する状態。修正時に1箇所を直し忘れるバグの温床になります。
巨大なクラス(Large Class / God Object)
1つのクラスがあまりに多くのフィールド・メソッドを抱え、無関係な責任まで担っている状態。
多すぎる引数(Long Parameter List)
関数が5個・6個と多くの引数を取る状態。呼び出し側での順序間違いを誘発しやすくなります。
分岐だらけの条件式(Switch Statements / 深いネスト)
同じ種類の条件分岐があちこちに散らばっていたり、if文が何重にもネストしている状態。
コード例で見るコードスメル
// スメルあり: 長すぎる関数 + 重複ロジック + 深いネスト
function processOrder(order) {
if (order) {
if (order.items && order.items.length > 0) {
let total = 0;
for (const item of order.items) {
if (item.category === "book") {
total += item.price * 1.08; // 書籍は8%軽減税率想定
} else {
total += item.price * 1.1;
}
}
if (order.coupon) {
if (order.coupon.type === "percent") {
total = total * (1 - order.coupon.value / 100);
} else if (order.coupon.type === "fixed") {
total = total - order.coupon.value;
}
}
return total;
}
}
return 0;
}
// 改善: 責任ごとに関数を分割し、ネストを浅くする
function calcItemsTotal(items) {
return items.reduce((sum, item) => sum + calcItemPrice(item), 0);
}
function calcItemPrice(item) {
const taxRate = item.category === "book" ? 0.08 : 0.1;
return item.price * (1 + taxRate);
}
function applyCoupon(total, coupon) {
if (!coupon) return total;
if (coupon.type === "percent") return total * (1 - coupon.value / 100);
if (coupon.type === "fixed") return total - coupon.value;
return total;
}
function processOrder(order) {
if (!order?.items?.length) return 0;
const total = calcItemsTotal(order.items);
return applyCoupon(total, order.coupon);
}分割後は各関数が単一の責任を持ち、それぞれ独立してテストできるようになります。
コードスメルを見つけるコツ
- • 関数名を考えるときに「〜して〜する」のように「と」でつながる場合は責任過多のサイン
- • 同じ処理を2回コピペした瞬間に、抽出のタイミングだと意識する
- • 静的解析ツールの複雑度(Cyclomatic Complexity)警告を無視しない
- • コードレビューで「読みにくい」と感じたら、それ自体がスメルの兆候
ポイント
- • コードスメルはバグではなく「設計上の問題を示唆する兆候」
- • 長すぎるメソッド・重複コード・巨大クラス・多すぎる引数・深いネストが代表例
- • 責任ごとに関数を分割することで多くのスメルが解消される
- • レビュー時の「読みにくさ」の感覚自体を見逃さない
確認クイズ
1 / 3コードスメルの説明として最も適切なものはどれか?