「ソースコードを汚くするには」に記載したようなコードを書いていると、結果的に複雑なプログラムになってしまいます。
ここでは複雑なプログラムに現れやすい傾向や特徴などについて記載しました
基本的にJavaをターゲットにして本エントリを記載しています
クラス定義
- import文に現れるパッケージが多種多様になっている
- 多様なクラスとの依存関係ができて複雑な状態になっている
- import文が異様に長い(importしているクラスが多い)
- import文が長いということは依存しているクラスが多いということ。結果的に複雑になっている
- クラスが大きい
- 責務が多すぎるためにクラスが巨大化している
- クラス名が長い
- 複数の責務を負わされたクラスはその名称が長くなる場合がある
- 定義されたpublicメソッドが多い
- インスタンス変数が多い
- クラス名とクラス内に定義されたメソッドが意味的に紐づかない
- もともとの責務の範囲を超えたメソッドが定義されてしまった可能性がある
- abstractクラスなのにでかい(重い実装を持っている)
- メソッド名が長い
- メソッド名に端的な名前を付けられないのは、他のメソッドとの区別をするために説明的な内容を記述しなければならないという状況を意味する場合がある。クラスの整理ができていないことに起因する。
- コンストラクタが多い
- 色んなタイプのインスタンスを生成するために多様なコンストラクタを定義しなければならなくなっている
- staticメソッドだけを持つクラスが多い
- staticメソッドだけを持つstaticなクラスに可変性を入れ込むのはかなり厳しい。そのため機能追加時や変更時などに柔軟な対応がしにくくなる
パッケージ
- パッケージ間の相互依存が発生している
- パッケージごとの役割の整理がうまくできていない場合にこのようなことが起きる
- 一方向の依存に比べて、相互依存は異常に複雑な状態を生み出す
nullの扱い
- メソッドの戻り値などに対する頻繁なnullチェックが行われている
文字列の扱い
- 各処理の中で文字列をtrimしている
- 頻繁なnullチェックなどと同じく渡された値が自分の欲している形になっていない可能性があるので、余計な処理をしなければならなくなっている
- 基本的にどこか一カ所でやるべき
例外の扱い
- 自分のLayerと無関係な例外をスローしている
- 下位メソッドからの例外をjava.lang.Exceptionでcatchしている
- 下位メソッドが複数の例外をスローしてきたり、実装に寄った例外をスローしてきたりした場合などに、例外の扱いが非常に煩わしくなり、java.lang.Exceptionで例外をまとめてcatchしてしまう状況をつくってしまう。
継承
- 継承元の親クラスをどんどん遡っていかないとソースコードの内容を理解できない
- 継承階層が深くなりすぎている。継承は使いどころを間違えると諸刃の剣となる
命名
- メソッドが機能追加によってそのコード量が増加した場合でもメソッド名が変わっていない
- 例えば機能追加によりコード量が当初よりも2倍,3倍に増えた場合に、普通に考えれば同じ名前(意味)で保ち続けられるはずはない。適切にメソッド名を変えるか、メソッドを上手く分割する等の対応が必要なはず。
if文
- ifの条件文が何を意味しているのか一見して理解できない
- "何の判断をしているのか?"ではなく"どうやって判断するのか?"という条件判定の実現方式になっているとソースコードを読む側は理解できない
ユニットテスト
- ユニットテスト時にテスト対象クラスのインスタンス化ができない
- ユニットテスト時に、実行対象のメソッドに渡すパラメータがインスタンス化できない
- ユニットテストしようとした際に、テスト対象のクラスと直接関係のない外部環境(DBやファイルやネットワーク環境など)のセットアップが必要になる