コードスメルとは
コードスメルとは、理想的な構造になっていないコードの部分のことです。コードの臭いですね。この概念は、マーティン・ファウラーが1999年に出版した「Refactoring: Improving the Design of Existing Code」*2の中で使い始めたものみたいです。コードスメルの例としては巨大すぎるクラスや複雑なswitch文などが例に挙げられます。
ファウラーの22のコードスメル
ファウラーは著書の中で22のコードスメルの一覧を紹介しています。以下の表がその一覧です。(自分なりの解釈が入ってます)
コードスメル | 説明 | 範囲 |
---|---|---|
長すぎるメソッド | 原則1つのメソッドに1種類の処理。 | メソッド |
多すぎる引数 | メソッドは多すぎる引数を受け取ってはならない。 | メソッド |
switch文 | 巨大なswitch文は作らない。インターフェースなどを使ってポリモーフィズムを利用すべき。 | メソッド |
クラスのインタフェースの不一致 | ぱっと見では違うけど、フィールドやメソッドが類似している複数のクラスは作らない。(インターフェースを実装しろってこと?) | クラス |
基本データ型への執着 | 一つのクラス内で基本データ型(プリミティブ型)を使いすぎないようにする。 | クラス |
未熟なクラスライブラリ | メソッドは適当なクラスに追加するのではなく、ライブラリクラスに追加する。(?) | クラス |
巨大なクラス | メソッドやフィールドが多すぎるクラスは作らない。 | クラス |
怠け者クラス | 小さな仕事しかしないクラスは作らない。 | クラス |
データクラス | データだけを保持するクラスを作るべきではなく、メソッドも追加すべき。 | クラス |
一時的属性 | クラスに不必要な一時的なフィールドを用意すべきではない。 | クラス |
データの群れ | 複数のデータがいつも同じ組み合わせになって使われているなら、クラスか構造体まとめる。 | クラス |
変更の偏り | 何か一つの変更を加える際に,多くの異なるクラスに小さな変更を加えなければならない状態。 | コード一般 |
特性の横恋慕(よこれんぼ) | クラスAのメソッドがクラスBから何度も参照されているなら、そのメソッドはクラスBに移動するとよいかも。 | コード一般 |
不適切な関係 | クラス同士の密な構造はだめ。 | コード一般 |
重複したコード | 同じようなコードは複数個所に書かないような構造が望ましい。 | コード一般 |
コメント | コメントはそのコードが何をするかではなく、なぜそのコードが必要なのかを説明する必要がある。 | コード一般 |
メッセージの連鎖 | メソッドがメソッドを呼び、さらにメソッドを呼びといったようなメソッドの長すぎる連鎖は避けるべき。 | コード一般 |
仲介人 | 責務をほかのクラスにたくさん委譲してるクラスは必要ないかもしれない。 | コード一般 |
パラレル継承 | あるクラスのサブクラスをつくるとき、別のクラスのサブクラスも作る必要があったとしたら、両方のクラスの機能を一つにまとめられる。類似した継承構造を持つクラス群が複数存在する状態。 | コード一般 |
相続拒否 | クラスが自身では使用しない挙動を継承している場合、その継承はいらないものかも。 | コード一般 |
変更の分散 | クラスに変更を加える際に,関係のない多数のメソッドに変更を加えなければいけない状態。 | コード一般 |
疑わしき一般化 | 「一応念のため」のコードは作らないようにする。 | コード一般 |
まとめ
リファクタリングするときなどは、これらを念頭に置いておくといいかもはかどるかもしれませんね。