プログラミング半年で学んだコードを良くするTips10選

## はじめに
現在でちょうどプログラミング歴半年ぐらいになります。
僕自身はまだまだで恐縮ですが、コードを良くするTips集を書いてみることにしました！

具体例はRubyで書いていきます。なるだけ、簡単な例にしますので
また、気になった点はコメントいただけますと嬉しいです。

## プログラミング半年で学んだコードを良くするTips
思いつくもの10個を書いていきます！
1. マジックナンバーをやめる
1. 名前重要
1. 基本、メソッドは動詞から変数は名詞
1. 統一感って大事
1. コメントには意図を書くようにする
1. 複雑な条件式などは説明変数に代入する
1. 副作用をメソッドに持たせない
1. 配列の順番に意味を持たせない
1. 基本コードは書きたくない
1. DRYの原則を守りましょう

それでは具体的な説明に入ります。
### 1. マジックナンバーをやめる
マジックナンバーとは直に記述された数字のことを言います。

```ruby: 例
puts 17
```
これでは、17てなんやねん！と思ったことでしょう。
では、以下ではどうでしょうか？

```ruby: 例
my_age = 17
puts my_age
```

どうでしょうか？17は僕の年齢だったわけです。
このように、数字の意味がわかるように変数や定数に入れるのをおすすめします！

### 2. 名前重要
プログラミングにおいて、名前が重要なんだと半年でやっと気づきました。
- どんな値が入っているのかすぐわかる変数名
- 何をするのか明確メソッド名

こういった命名の一つ一つがコードを読みやすくしているのだと思いました。

```ruby: Badな例
# これは極端だが、パッと何をしているかわからない
number = 17

def foo(num)
  num >= 18
end
```

```ruby: Goodな例
# 何をしているか、どんな意味かがわかりやすい
age = 17

def adult?(age)
  age >= 18
end
```

また、いい名前が思いつくまでは手を動かすべきでない？といった意見も聞いたりします。
確かに、いい命名が思いつくときは結構ロジックもある程度組めててスラスラいけてますね。

### 3. 基本、メソッドは動詞から変数は名詞
名前に関連して、基本的に
- メソッド → 動詞から
- 変数 → 名詞型

になります。

```ruby: Badな例
display_message = 'タスクを作成しました'

# タスクをDBに保存するメソッド
def task_create
...
end
```

```ruby: Goodな例
message = 'タスクを作成しました'

# タスクをDBに保存するメソッド
def create_task
...
end
```

他にも、配列は語尾に`s`をつけるなどもありますね。
ただ、例外もあります。処理しないメソッドは名詞でも構わないことです。

```ruby: 例
# 名前かメールを返す(DBに保存や削除などの処理をしてない)
def name_or_email
  name.presence || email
end
```

詳しくは下記の記事などを参考にしていただければと思います↓

https://qiita.com/jnchito/items/459d58ba652bf4763820

### 4. 統一感って大事
コードは統一感があった方がいいです。
「あっちではこう書いてるのに、こっちではこんな書き方をしている！」というのを避けましょう。混乱が起こるので

例えば、`boolean`が入る変数の命名で`is_`を使うのか？使わないのか？などがあります。
```ruby: Badな例
is_new_adult = age == 18

# またとあるところでは
adult = age >= 18
```
これでは、`is`をつけるのかい、つけないのかい、どっちなんだい案件です。
```ruby: Goodな例
is_new_adult = age == 18

# またとあるところでは
is_adult = age >= 18
```

こんな感じでチーム内で統一しましょう。

### 5. コメントには意図を書くようにする
コメントにはコードの意図(Why)を書くようにしましょう。
僕が初めてチーム開発に入れてもらったときは、「全部のメソッドの上に処理をコメントで書いてくれ〜〜」って思ってたのが懐かしいです笑

コードを解説するコメントを書くよりも、わかりやすい命名や処理をするように心がけましょう。
そこで、コメントにはWhyを書くようにしましょう。

```ruby: 例
# 〇〇なため暫定対応
def zantei_method
...
end
```

ここら辺の塩梅は半年ではまだなれないですが、あとで見たときになぜこう書いているのかわからないだろうな、という箇所にコメントをふっています。

また、`TODO`コメントなどもよく使います。
```ruby: 例
# TODO: テストコードを書く
def full_name
...
end
```

### 6. 複雑な条件式などは説明変数に代入する
パッと見て、なんだこれは！？と疑問に思う処理などには名前をつけましょう。
これによって行は増えるのですが、トータルで読む時間が減ります。

下記ではボウリングのストライクとスペアで質問しているコードです。
```ruby: Badな例
if frame[0] == 10
  puts 'あなたはボウリング仙人ですか？'
elsif !(frame[0] == 10) && frame.sum == 10
  puts 'あなたはプロボウラーですか？'
end
```

```ruby: Goodな例
strike = frame[0] == 10
spare = !strike && frame.sum == 10

if strike
  puts 'あなたはボウリング仙人ですか？'
elsif spare
  puts 'あなたはプロボウラーですか？'
end
```

説明変数に入れた方が読みやすくなりました。
個人的に推しTipsの一つです。

### 7. 副作用をメソッドに持たせない
メソッドの処理を追ってるうちに、「こんなこともやってたのか！？」となるメソッドはNGです。
メソッドの責務は一つにして、これをするメソッドです！と言い切れるようにしましょう。

あまりいい例が思いつかなかったのですが、下記コードを参考までに
```ruby: Badな例
def calculate_total_point(student)
  total_point = student.test.points.sum

  # ここで、ランキングの計算もする(副作用)
  ranking = fetch_ranking(total_point)

  { total_point:, ranking: }
end
```

```ruby: Goodな例
def calculate_total_point(student)
  student.test.points.sum
end
```

ランキングの計算まではメソッド名からわからなかったので、びっくりしてしまいます。
こういったメソッドはやめましょう。

### 8. 配列の順番に意味を持たせない
配列の順番に意味を持たせないようにしましょう。
皆さんは生徒のテストの点数をデータとして扱うときに、
- 1番最初が国語で
- 2番目の値が数学で...
- 3番目の値が社会で...

よし、〇〇くんの国語の点数を知りたいから`array[0]`だ！みたいなのはハッシュにしましょう
```ruby: 例
test_result = { japanese: 55, math: 60, society: 50 }
```
ハッシュの方が、モログラミングでなく、カタグラミングになりました
こちらは、下記の記事が参考になると思います。伊藤さん、ありがとうございます！

https://qiita.com/jnchito/items/fb4ed2238ee3404b4403

### 9. 基本コードは書きたくない
基本的にコードは書かないに越したことはないです。
というのも、自分で書く前にすでに書いている人はいないか？(ライブラリが使えないか？)という視点を持つのが大事です。

コードの量が少ない方がメンテナンスもしやすいです。
また、メンテナンスもライブラリ作成者がしてくれるのでその分時間の節約にもなります。

車輪の再発明をしないという言葉もあります。
つい、コードを書くのは楽しいので書きたくなりますが、そこら辺は怠惰にいくべきです。

### 10. DRYの原則を守りましょう
プログラミングにはDRYの原則があります。
それは、「コードを重複させない」ということです。

厳密には違うみたいなのですが、ややこしいので「重複させない」でいきます。
同じようなロジックが出てきたら変数やメソッドにまとめましょう。

```ruby: Badな例
def train_maccho
  distance = 70 * 0.1
  having_amount = 70 * 0.05

  run(distance)
  have_lanch(having_amount)
  swim(distance)
end

def train_child_maccho
  distance = 40 * 0.1
  having_amount = 40 * 0.05

  run(distance)
  have_lanch(having_amount)
  swim(distance)
end

train_maccho
train_child_maccho

```

```ruby: Goodな例

def train(goal_weight:)
  distance = goal_weight * 0.1
  having_amount = goal_weight * 0.05

  run(distance)
  have_lanch(having_amount)
  swim(distance)
end

train(goal_weight: 70)
train(goal_weight: 40)
```

こんな感じになります！参考までに

## おわりに
プログラミングを始めてもう半年、わからないことだらけでしたが徐々にわかるようになってきました。
ただ、僕自身プロとは程遠いのでまだまだ頑張ります。

また、教えていただいた先輩エンジニアの皆さんありがとうございます！
これからもぜひ教えていただけますと嬉しいです。

いいねとかもしてもらえると超喜びます笑
それでは！