プログラミングを始めて少し経つと、たくさん検索をしながらも少しずつコードがかけるようになってくると思います。
ただ何かを作っていると、少し複雑な実装が必要になってきたときに何と調べたらいいかわからなくなったり、試行錯誤しながら実装している間に混乱してきてよくわからなくなったり、あとで読み返せないくらい混沌としたコードになっていたりと、次々と新しい壁が立ちはだかりますよね。
いざそれらを解決していくために「コーディングのレベルアップがしたい」「綺麗にコードを書こう」と思っても、実際に何から始めていけばいいのか悩むと思います。
今回は、筆者が実際に社内でプログラミング経験の無い社員やインターン生に教えていく際に試行錯誤しながら発見していった、エンジニアとしての成長速度が上がる習慣を紹介していきます。
最初のうちはプログラミングは複雑で難しいものに感じますが、実は多くの初心者の方がそれをさらに自分のプログラミング習慣で複雑にしてしまっています。
言語やプログラミングの理解度がいきなり上がったり、急にガリガリかけるようになったりはしないので、慣れるまでの間は、取りはらえる複雑さは取り払ってしまいましょう。
今回紹介するコーディング習慣はあなたのプログラミングをとにかくシンプルにしてくれるものです。
習慣になるまでは少し面倒かもしれませんが、適切なコーディングの習慣を身につけると、実装速度だけでなく、成長速度にもダイレクトに影響が出るので、ぜひ快適な習慣を身につけてください。
もし以下に当てはまるものがあれば、きっとこの記事はあなたの力になれると思います。
- 「コメントを書こう」ってよく見るし理解してるけど、どう書けばいいかしっくりきていない
- 「インデントを揃えよう」ってよく見るけど、なんで揃えた方がいいのかしっくりきていない
- 「動くものは書けるようになってきた」し「なんとなく修正はできる」けど、「壁にぶつかったらものすごく時間がかかる」
- 実現したいことと全く同じサンプルコードがあるものは実装できるけど、ないと実装できない
- 複雑な実装がまだ苦手
今から実践できるごく簡単な3つのコーディング習慣
今回は下の3つの習慣を紹介しようと思います。
1. インデントを揃えよう
2. ツイッターにつぶやくようにコメントを書こう
3. 一度に考えることを減らしながら処理を書こう
これから詳しくこの3つの習慣を紹介していきますが、最初の二つはよく聞く話だと思います。
業界的に、いつもは「こうしなきゃダメ」「こうしなきゃクソ」みたいな過激な表現がされることが多いものですが、今回はぜひ「自分の実装と成長を助けてくれる」ものとして改めて受け取ってみてください。
「もうできてるよ」というものがあれば、そこを読み飛ばしてもらっても大丈夫です。
インデントを揃えよう
一番基礎的な項目ですが、もしまだあなたがこれを実践していないなら、あなたの伸び代がぐっと増える習慣なので、全ての下地になると思ってすぐに実践しましょう。
というのも、少し大げさに言えば「インデントを揃える」というのは、おそらく今後の長いプログラミング人生における一番多くの時間を節約するための行動だからです。
誰にでもわかりやすいようにあえてプログラミング言語ではなくマークアップを取り上げますが、まずこれを見てください。
[ruby]
<section>
<div><a href=”https://www.hogehoge.com”>詳しくはコチラ
</a>をクリックしてください。
</div><div><p>こんにちは
</p></div>
</section>
[/ruby]
あまりに極端ですが、この量でも既にとても見辛いですね。
このコードを修正しようと思ったとき、まずどこまでが一つの括りなのかを確認するところから始めなければいけません。
でもこれが
[code lang=”html”]
<section>
<div>
<a href=”https://www.hogehoge.com”>詳しくはコチラ</a>をクリックしてください。
</div>
<div>
<p>こんにちは</p>
</div>
</section>
[/code]
となっていると、一つの括りがどこからどこまでなのかがすぐにわかるので、目的の場所をすぐに修正することができます。
「コードが綺麗にそろっている」というのは、後で見たときの「コードブロック(括り)を確認する」という無駄な行動を減らしてくれます。
例ではマークアップを利用しましたが、実はこの「インデントが揃っていない」という状態はマークアップに限らずプログラミングにおいても「あなたのコーディングの仕方が複雑である」というサインである可能性が高いのです。
あくまで筆者の主観になりますが、インデントが揃っていない初心者の多くは「一度に多くのことを考えながらコードを書いている」ことが多く、これはコードを書いていくフローが複雑になっていることが反映されているんだろうなと感じています。
ここについて、詳しくは3番目の習慣で触れようと思いますが、
まずは「インデントを揃える」ということを意識して書いていってみてください。
ちなみに色々なエディタでインデントの設定が若干違ったりもしますが、基本的にはtabキーを1回押した「半角スペース二つ分」が1インデントになります。
もしそうなっていないエディタの場合は、設定からtabキーを押した時のインデントのかけかたを設定できるので、半角スペース2つ分を設定してみてください。
インデントは作業時間を大きく短縮してくれるもの。
「揃えるのが面倒だな」と感じたら、それはコーディングの仕方が複雑になっているサイン。
ツイッターにつぶやくようにコメントを書こう
「コメントを書く」というのは案外難しく、慣れるまではコストも高く、「何をやっているのかではなく、なぜやっているかを書こう」と言われても中々実行できない方が多いかと思います。
そこで最初のうちは「ツイッターにつぶやくようにコメントを書く」ということをやってみてください。
例えばrailsなら、
[code lang=”ruby”]
# せっかくpublished_atで公開状態を管理してるから後々予約投稿の機能とかつけたいなー
Page.find(params[:page_id]).update(published_at: Time.current)
# 車,雑談とかの指定された複数のTagを全部持ってるページを取得する実装したいけど難しすぎ..どれかなら簡単なのに…みんなどうやってんの?とりま諦めてどれかを含む検索にした。
pages = Page.eager_load(:page_tags).where(page_tags: {tag_id: params[:tag_ids]})
[/code]
のような感じです。職場では中々使いづらいと思うので、自分のプロジェクト等の許される環境で試してみてください。
難しく考えず、いつも通り呟くような感じで書いていきましょう。
というのも実はコードの書き手の心情はとても有用なんです。
なぜなら、他の人や未来の自分がそのコードを読んだ時「わからなくてそう書いている」のか「仕様通りでそう書いている」のかが一目でわかるからです。
もしコメントに悩んだ様子が書かれている時は、「あぁ、単純に習熟度の問題でこう書いてるんだな」と把握して手直しすることが容易になりますし、
「面倒だけど〇〇の関係でこうするしかないっぽい」などと書かれていた場合は、そのファイルや前後には現れていない、何かとの依存関係によってそう書かれているんだなとわかり、安易な修正を行ってエラーを引き起さずにすみます。
コメントつけることに慣れてきたら本来のように
[code lang=”ruby”]
# TODO : Time.currentを変数にして予約投稿機能つける
Page.find(params[:page_id]).update(published_at: Time.current)
# FIXME : 本当は指定された複数のTagを全部持ってるページを取得したい
pages = Page.eager_load(:page_tags).where(page_tags: {tag_id: params[:tag_ids]})
[/code]
みたいに型にはめていくといいと思います。
このようなステップを踏むのは「適切なコメントがつけられる」というのは一つの能力であって、これもプログラミングと同じように或る日突然できるようになるものではないからです。
実は適切なコメントをつけるためには、適切な単位で関数を実装したり、自分の思考が整理されたりしている必要があるので、「コメントを書く」という行動そのものがあなたのプログラミング能力を押し上げてくれます。
なのでまずはいつも自分がやっているような、ハードルの低い方法で「コメントを書く」という習慣を身につけるところから始めてみてください。
慣れるまでは難しく正しく書こうとせず、Twitterに呟くようにコメントを書いていく。
コメントを書くことそのものがプログラミング能力を向上させてくれる。
一度に考えることを減らしながら処理を書こう
例えば、「有料会員で姓がある場合は姓と名のデータを結合して返し、有料会員で姓がない場合は名だけを返し、無料会員の場合は[無料のユーザー]という文字列を返す」という実装をすることになったとして、あなたはどんな風に処理を書いていくでしょうか?
初心者の方が実装でつまづいている時に、僕がいつも提案しているのは「一度に考えることを減らしていきましょう」ということです。
今回もRailsを使ってどういうことかを説明していきます。
自分がよく書いている言語でイメージしてみてください。
状態1
[code lang=”ruby”]
def display_name(user:) # 後で閉じend書かなきゃ
# 有料会員かどうか判別しなきゃ
[/code]
状態2
[code lang=”ruby”]
def display_name(user:) # 後で閉じend書かなきゃ
if user.is_subscribed # 後で閉じend書かなきゃ
# 姓があるかどうか判別しなきゃ
[/code]
状態3
[code lang=”ruby”]
def display_name(user:) # 後で閉じend書かなきゃ
if user.is_subscribed # 後で閉じend書かなきゃ
if user.last_name.present? # 後で閉じend書かなきゃ
# 文字列を結合して…
[/code]
のように書いていくと、どんどん頭の中に「やらないといけないこと」が溜まっていきます。
そして考えないといけないことが沢山になって混乱したり、うっかりその一つを忘れてしまっていたり、考慮漏れをしたりと、辛いコーディングになる上に、混乱した頭で書いているので読みにくいコードになってしまいます。
そして1つめの習慣でも触れたように、インデントが揃っていないコードはこの状態で書いています。
1つ1つ小さい作業を終わらせていくとインデントを揃えることは簡単なのですが、
一度に何個も作業を同時並行で行なっていると、自分でも括りがよくわからなくなったり、面倒に感じてしまい「インデントを揃える」ことができなくなってきます。
これを一度に考える量を減らすように書いていくことで、余計な混乱を防ぐことができ、
実装の速度を上げながらシンプルで読みやすいコードが書けるようになります。
ルールは簡単で、
1. やりたいことを日本語で書く
2. タスクを一つずつ終わらせる(簡単な処理を書く/ifは先に閉じる/かっこは先に閉じる)
3. 複雑になりそうな処理の実装は後回しにして、全体の処理の流れだけを先に完成させる
の3つだけです。
実際に見てみましょう。
状態1
[code lang=”ruby”]
# 表示名を返す関数を作る
def display_name(user:)
“返す文字列”
end
[/code]
状態2
[code lang=”ruby”]
def display_name(user:)
# 無料なら「無料のユーザー」を返す
# 有料で姓がない場合は名だけを返す
# 有料で姓がある場合は姓と名を返す
“返す文字列”
end
[/code]
状態3
[code lang=”ruby”]
def display_name(user:)
# 無料なら「無料のユーザー」を返す
return “無料のユーザー” unless user.is_subscribed
# 有料で姓がない場合は名だけを返す
# 有料で姓がある場合は姓と名を返す
“返す文字列”
end
[/code]
状態4
[code lang=”ruby”]
def display_name(user:)
return “無料のユーザー” unless user.is_subscribed
# 無料のユーザーがここから下のコードに到達することはないので、
# 「有料なら」のようなイディオムが省ける。
# 有料で姓がない場合は名だけを返す
return user.first_name unless user.last_name.present?
# 有料で姓がある場合は姓と名を返す
“返す文字列”
end
[/code]
状態5
[code lang=”ruby”]
def display_name(user:)
return “無料のユーザー” unless user.is_subscribed
return user.first_name unless user.last_name.present?
# 姓がないユーザーがここから下のコードに到達することはないので、
# 「姓がなかったら」のようなイディオムが省ける。
# 有料で姓がある場合は姓と名を返す
user.last_name + ” ” + user.first_name
end
[/code]
という風に書くことになります。
この書き方以外にももちろん色々な書き方はありますが、下に進むにつれて「無料なら」や「姓がなければ」のような条件のことを考えなくて良くなっていくので、どんどん考えることが少なくなっていくのがわかると思います。
これはhtmlや他のプログラミング言語を書く時でもアプローチの仕方は同じです。
そして、例えば先ほどの要件の最後に「有料で姓がある場合はuserがこの1週間にお気に入りした商品の数をつけて返す」のような処理が加わった場合は、
[code lang=”ruby”]
def display_name(user:)
return “無料のユーザー” unless user.is_subscribed
# 有料で姓がない場合は名だけを返す
return user.first_name unless user.last_name.present?
# 有料で姓がある場合は姓と名を返す
name = “#{user.last_name} #{user.first_name}”
# お気に入りした商品の数をつけて返す
favorite_count = 3
“#{name} : お気に入り商品は#{favorite_count}品です。”
end
[/code]
のように、「お気に入りした商品の数をもらってくるものとして」固定の数字を書いておき、先に全体の処理だけを完成させてしまいましょう。
最後にfavorite_countのところをどうやってもらってくるか考えて実装して、3の数字と入れ替えれば実装は終わりです。
そうすれば、「この後どうしないといけないんだっけ?」と思い出す時間を省けますし、うっかり実装漏れをしてしまうことも少なくなりますね。
このように書いていくことによって、頭の中にある「今考えること」が常に少数に保たれるので、とても楽にコードが書けるようになっていきます。
そしてこの「一つの関数内で作業を細かく細分化する」という行動は、混乱が減って無駄なミスが減るだけでなく、
あなたが成長した先で重要になる「関数を適切に分割する」というプログラミング能力に直結してきます。
この例でいくと、複雑になりそうだからと後回しにしたfavorite_countを取ってくる処理が複雑になっていくような場合は、そのロジックをこの関数内で書かずに別の関数に切り出すことになるかもしれませんね。
今そこまで関数の粒度や再利用性を気にしながら書いていかなくても大丈夫ですが、もしいつかあなたがそのフェーズに差し掛かったときに、きっと今回の習慣がさらにあなたの成長速度を加速させてくれるはずです。
1. やりたいことを日本語で書く
2. タスクを一つずつ終わらせる(簡単な処理を書く/ifは先に閉じる/かっこは先に閉じる)
3. 複雑になりそうな処理の実装は後回しにして、全体の処理の流れだけを先に完成させる
のルールを基準にしながら、「一度に考えることを減らす」ようにコードを書いていく。
おわりに
今回は言語に関係なく、なんの言語を書いている人でも成長の助けになる、汎用的なプログラミングの習慣を紹介してみました。
一貫してこれらの習慣は、「物事を分割して小さくシンプルにする」という能力を細分化して行動に落とし込んだものになります。
そして、これはプログラミング全般の下地になる能力なんじゃないかなと、個人的には考えています。
この記事自体も「プログラミング能力をあげる」という目的を「分割して行動可能なところまでシンプルにする」ことによって書かれているので、もしかするとプログラミング以外にも使えることなのかもしれません。
いつかあなたが複雑で大きなシステムを作るとき、実装一つ一つにおいて考えることを少なくしていくことがより重要になっていくでしょう。
依存関係が少なくなるように、修正に強くなるように…実装そのものよりもむしろその設計にこそプログラミングの面白さと醍醐味があるのかもしれません。
というわけで、あなたも是非シンプルなコーディングライフを送ってください。