Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

[扱いにくいコードについて考える] 理解しにくいのってどんな時?

なんのための記事か

ここでは自分が考える扱いにくいコード例を列挙し、それに対して自分なりに理由付けします。

なぜするのか

リファクタリングの本を読んでいます。

自分の経験に紐づけて読み進めようと思い、まずは扱いにくいコードって何かということについて考えることにしたためです。

扱いにくいにくいコードとは?(「読みにくい」含む)

  1. インデントが深い
  2. 条件分岐が多発している
  3. メソッドが長い
  4. メソッドに返り値がない
  5. メソッドの名前から直感的に処理内容がわからない
  6. 共通化されすぎている
  7. 記述が横に長すぎる
  8. 名前が長すぎる
  9. 巨大なクラス
  10. クラス変数がいたるところで参照されている
  11. 引数が多い

それぞれの理由

1. インデントが深い

これが読みにくい理由は以下の4点かと思います。
1. 記述が横に長くなる傾向になるから
2. 処理の内容に加えて条件についても考える必要があり、頭の中での処理内容が多くなるため。
3. 条件分岐で関係ないところについては、理解の度合いが関係あるところに比べて浅くなります。馴染みの浅いコードを見ると心理的に負担がかかるから?
3. 単純に条件分岐について考えるのは頭にかかる負荷が大きい?

通常の処理ならインデントはだいたい揃います。
インデントのずれが発生するのは、通常の処理ではなく条件分岐が発生している時が多いです。
例えば以下のような感じ。

インデントが深くなる時.java
methodA();
methodB();
if (どこかの画面から遷移してきた時) {
  if (name != null) {
    switch(largeCategoryId) {
      case C:
        methodC();
        break;
      case D:
        methodD();
        break;
    }
  }
}

普通にありえそうですね。nullチェックとswitchを使うとインデント深くなっちゃうので、なんとかしたいです。

2. 条件分岐が多発している

  1. 条件を判定する処理は頭に負担がかかる
  2. 条件の組み合わせを覚えるのが大変
  3. 記述が横に長くなっていく
  4. 変更する時に、条件分岐を変更するのはかなりデリケート。単純に条件を追加するだけ?どこかの条件分岐が一緒になったりする?
  5. コードが詰まっているように見える。(改行すれば解消されるかもしれないですが、変な改行を入れると無意味に見えるので、それはそれでコードが冗長に見えてしまう)
条件分岐が多発している.java
if (age >= 20) {

  if (gender == male) { // この一行上の改行は意図がわからないので、冗長に見える
    methodA();
  } else {
    methodB();
  }
} else if (age == -1) {// かといって↓のように改行を全くしないと詰まって見えるので読みづらい
  if (gender == male) {
    methodC();
  } else {
    methodD();
  }
} else {
  methodE();
}

3. メソッドが長い

  1. メソッドを読み終わるまで、内容を一通り覚えておく必要がある。メソッドが長いと、覚えておく必要があることが増えて脳に負担がかかる。
  2. 読み始めるのにかなりの決意を必要とする。そのため心理的に負担がかかる。
  3. 再利用が難しい。

4. メソッドに返り値がない

  1. 何をするメソッドなのか内容を読まないとわからない。
int sum = 1;
boolean result = false;
String value = "";

methodA();
methodB(value);
methodC(sum);

return result;
int sum = 1;
boolean result = false;
String value = "";

value = methodA();
sum = methodB(value);
result = methodC(sum);

return result;

例としては全く適当なメソッドを並べただけですが、返り値があるだけでなんとなく各メソッドの処理内容が予想できます。
そのため、各メソッドを読み始める時の心理的負担が低くなります。

5. メソッドの名前から直感的に処理内容がわからない

  1. メソッドの内容をきっちり覚える必要があるため、脳に負担がかかる
  2. 軽く読み流したい場所でも、ちゃんと読まなきゃいけなくなるため、脳に負担がかかる

6. 共通化されすぎている

きちんと共通化できるところならいいのですが、無理やりやっていると以下のようなことが起こります。
1. 条件分岐が多くなる。
2. クラスの場合は、クラス、メソッドそれぞれ命名が最適化されないのでコードを読まないとわからないところが多くなる。
3. 条件分岐が多くなるので、不要な処理もそれだけ増えます。そのためクラスも肥大化しやすい。

7. 記述が横に長すぎる

  1. 意識的に目で追う範囲を広げなければならないので、考えることに割くエネルギーがその分減る
  2. 画面内に入らない場合には、画面を指で横スクロールしなければならないので、考えることに割くエネルギーが減る
  3. 対象の行の行末を読んでいる時に、左に何が書いてあったかを意識する必要があるので、脳に負担がかかる

8. 名前が長すぎる

  1. 記憶する情報量が多くなるので、脳に負担がかかる

9. 巨大なクラス

  1. 読まなきゃいけない量が単純に多くなるので、脳に負担がかかる
  2. 読み始めるために、かなりの決意が必要になるので、心理的に負担がかかる

10. クラス変数がいたるところで参照されている

  1. コードを変更すると、思わぬところで副作用が発生する可能性がある

11. 引数が多い

  1. 渡すべき引数を渡し忘れる可能性大
  2. 渡すべき順番を覚えられない
  3. 再利用しづらい
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?