はじめに
こんにちは、新卒2年目・TIG所属の栗栖です。
秋のブログ週間2023の9本目です。
コードレビューで拡張性・保守性の観点からご指摘を頂いたことをきっかけに、今後の実装を改善すべく、良いコード/悪いコードで学ぶ設計入門―保守しやすい 成長し続けるコードの書き方という書籍を読みました。
書籍の指す「良いコード」とは何かについてと、個人的に印象に残った箇所を紹介したいと思います。
良いコードとは
書籍には低凝集、高凝集という単語が頻繁に登場しており、凝集度(ぎょうしゅうど)をコードの善し悪しを評価する指標としています。
凝集度とは、「モジュール内における、データとロジックの関係性の強さを表す指標」です。
高凝集な構造は、変更に強い、望ましい構造です。逆に低凝集な構造は、壊れやすく変更が困難です。
つまり良いコードとは高凝集な構造で、モジュール間が密接に関わっている状態ということです。
悪いコードは低凝集な構造であり、再設計やリファクタリング等を行いデータとロジックの関係性を強化を行う必要があります。
印象に残った箇所
可変と不変の取り扱い方針
変数宣言時に可変にするか不変にするかについては、基本不変で良いみたいです。
不変にするメリットとして以下を挙げています。
- 変数の意味が変化しなくなるので、混乱が抑えられる。
- 挙動が安定し、結果を予測しやすくなる。
- コードの影響範囲が限定的になり、保守が容易になる。
フールプルーフ1の観点からも、可変と比べて高凝集だと思いました。
最近では、Rustなど不変がデフォルトの言語が登場しているようです。
下記ケースの場合は、可変を採用すべきと述べています。
- インスタンス生成に時間がかかり、パフォーマンスが怪しい
- ループカウンタなどスコープが局所的である
採用ケースがほとんどないのであれば、不変がデフォルトな言語が存在するのも納得しました。
プリミティブ型に執着しない
ほとんどプリミティブ型だけで「動くコード」を書くことはできるでしょう。しかし、それでは強く関係し合うデータとロジックをうまく凝集できません。このため、バグを埋め込みやすくなったり、可読性が低下したりします。
例えば引数の型をプリミティブ型からクラス型に変換することで、意図しない値渡しを防げたり、クラスに関連性の高いロジックとなるため、高凝集な構造になります。
プリミティブ型だけで実装せず、クラス設計の習慣をつけたいと思いました。
フラグ引数
フラグ引数付きのメソッドは、何が起こるか読み手に想像を難しくさせます。何が起こるのか理解するには、メソッド内部のロジックを見に行かなければなりません。可読性が低下し、開発生産性が低下します。
割れているロジックが1つにまとまるので実装しがちだったのですが、明らかに壊れやすく変更が困難なので今すぐやめます。書籍ではDRY原則2の誤用とされています。
外部へ渡す場合はコレクションを変更できなくする
>class Party {
>// 中略
>/** @return メンバーリスト。ただし要素の変更はできません。*/
List < Member > members() {
return members.unmodifiableList();
}
JavaではunmodifiableList
で読取り専用にし、要素の追加や削除を不可能にできます。
そのまま外部へ渡すと、勝手な操作をされる可能性から低凝集になってしまうため、他モジュールからの引数を読み取り専用にしたり、変更して欲しくない値を外部に渡す際は必須テクニックだと思いました。
神クラス
神クラスとは、1クラス内に何千何万行ものロジックを持ち、あらゆる責務のロジックが、乱雑に絡み合うように書き殴られているようなクラスです。
開発者の時間を奪い、多大な労苦を与えて疲弊させてしまう、恐ろしい力が宿っています。
巨大なクラスは責務ごとに分割し、メインロジックは100行を超えない程度を目安とします。
名前が付いていたことに驚きました。
さいごに
文字がぎっしりと詰まったような書籍でなく、簡単なソースコードを例にして説明されていたため読みやすかったです。
16章ではFutureのコーディング規約も紹介されていました。開発環境がJavaの方は実装の参考になると思います。
今後の設計・開発では凝集度を常に考えながら、拡張性・保守性の高い成果物を目指します!
次は大野さんの魔法使いが夜更かしする場所です。