【新人プログラマ応援】学習用のプログラムと仕事で書くプログラムは何が違うか

## はじめに

これはQiitaで開催されている「新人プログラマ応援 - みんなで新人を育てよう！」イベントの投稿記事です。

https://qiita.com/official-events/63aa63fd921659fb3b5d

今回は「先輩（ベテランから2年目社員、上級生）からのアドバイス」を書いてみようと思います。

### この記事を書いている人

- 仕事で20年近くプログラムを書いているプログラマ
- 現在は[株式会社ソニックガーデン](https://www.sonicgarden.jp/)でRubyプログラマをやっている
- Rubyの入門書「[プロを目指す人のためのRuby入門](https://amzn.to/3walAWK)」を出版している
- プログラミングスクール「[フィヨルドブートキャンプ](https://bootcamp.fjord.jp/)」のメンターでもある

### 対象読者

- 現在プログラミングを学んでいて、将来プログラマ（特にWeb系）として就職したいと考えている人
- もしくはこの春から新人プログラマとして仕事でコードを書き始める人
- いずれも業界未経験の初心者プログラマを想定

僕が普段Railsを使っているため、この記事ではRailsを使う開発の現場を想定していますが、大半の内容はWeb系企業であれば言語やフレームワークを問わず参考になるはずです。

### この記事の趣旨

学習用のプログラム（技術書のサンプルプログラムやプログラミングスクールで出されるプログラミング課題等）と仕事で書くプログラムの大きな違いをあれこれ書いてみます。

実務経験がない初心者プログラマのみなさんは「動いたからこれでOK」もしくは「ちゃんと動かすだけで精一杯」と考えがちになるかもしれませんが、「いやいや、仕事でコードを書くとなるとそれだけではダメなんですよ」ということを伝えるのがこの記事の趣旨です。

それでは以下が本文です。

## 仕事で書くプログラムはめちゃくちゃ規模が大きく、仕様も複雑

学習用のプログラムはせいぜい数ファイル、1ファイルあたり数十行〜百行程度ですが、仕事で書くプログラムはめちゃくちゃ規模が大きく、仕様も複雑です。
プログラムは大量のディレクトリやファイルに分かれており、それぞれのファイルがものによっては数百行〜数千行の規模を持ちます。

学習用のプログラムは多少コードの重複があっても、目で追いかければ同じような修正を繰り返し適用できますが、仕事で書くプログラムはそうはいきません。
コピペでコードを書いていくと重複したコードがあちこちに分散します。
たとえば消費税の税率を"8%"から"10%"に変えたい、と思っても、1.08が分散していると「すべての1.08をヌケモレなく1.1に変更する」という作業は非常に神経を使います。
そうならないように、コードをDRYにする（Don't repeat yourself = 重複を避ける）必要があるのです。

### 「大きくて複雑」って具体的にはどれくらい？

仕事で書くプログラムが大きくて複雑、と言われても、実務経験がない人にはイメージが付きにくいかもしれません。

たとえば、フィヨルドブートキャンプで開発・運用しているRails製のEラーニングシステムはGitHub上でソースコードが公開されているので、これを見てみると多少雰囲気がつかめるのではないでしょうか。

https://github.com/fjordllc/bootcamp/

`app/models`ディレクトリを見ると60個以上のファイルが並んでいます。

- https://github.com/fjordllc/bootcamp/tree/main/app/models

Userクラスのソースコードは500行を超えています。

- https://github.com/fjordllc/bootcamp/blob/main/app/models/user.rb

自分一人で学習用にRailsアプリケーションを作っている場合は、なかなかこの規模にはいかないはずです。

仕事で書くプログラムはこれでもたぶん中規模くらいです。
世の中にはもっともっと大きなプログラムがあります。
たとえば、こちらのスライドで紹介されている会計freeeの事例は「もっともっと大きなプログラム」の一例でしょう。
<script async class="speakerdeck-embed" data-id="0f94988fc207469f8dd482c29d55b5ee" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>

仕事でコードを書くときは、こういったコードと立ち向かわなければいけないのです。

## 自分一人ではなく、チームで開発する

学習用のプログラムを読み書きするのは自分一人ですが、仕事では複数のメンバーでひとつのシステムを開発していきます。
最初から最後まで同じチームメンバーである保証はなく、むしろ「すでに退職してしまった開発者」や「あなたのあとから参加する開発者」もたくさんいます。

そうなってくると、「自分にしかわからないコード」は他の人の迷惑になります。
反対に「他の誰かが書いた意味不明なコード」は自分にとって大きなストレスになります。

よって、わかりやすい変数名やメソッド名を付けたり、チーム全体でコーディングルールを守ることが非常に大事になってきます。

たとえば、以下のようなコードは学習用のプログラムでは許されても、チーム開発の中では他の人から意味不明なコードと見なされます。

```ruby 
x = 1.1
b.price * x
```

最低でも次のように「中身がわかる変数名」を付ける必要があるでしょう（注：[丸め誤差の話](https://qiita.com/jnchito/items/d0ef71b25732ad5a881c)はここでは無視します）。

```ruby 
tax_rate = 1.1
book.price * tax_rate
```

## プログラムの寿命が長い

学習用のプログラムは学習したらそれっきりになりますが、仕事で書くプログラムの寿命は基本的に年単位です。現場によっては何十年も前に書かれたコードを保守し続けている、というようなケースもあるでしょう。

仕事で書くプログラムはずっと使われて、ずっと読み書きされるからこそ、わかりやすいコードを書くことが大事になってきます。

あ、そうそう、プログラムの寿命が長いと「過去の自分」も完全に他人になっちゃいます。
これは何の話かというと、「昔の自分が書いた意味不明なコードに、現在の自分が苦しめられることがある」ということです。

https://twitter.com/jnchito/status/1158925683713646592

## rails newする機会は数年やってこない

Ruby on Railsで学習用のプログラムを作るときは十中八九`rails new`でゼロからRailsアプリケーションを作り始めると思います。

ですが、あなたが新人プログラマとして就職したら、いきなり`rails new`する仕事を与えられることはまずありません。
あなたが最初に担当するタスクはほぼ間違いなく、既存のRailsアプリケーションの機能追加や不具合修正になるはずです。

業務で本格的に使われるシステムを`rails new`する機会が出てくるのはおそらく、入社して数年経ち、あなたが新規のプロジェクトをリードできる上級プログラマと認められるようになってからです。

ですので、新人プログラマとして必要になるスキルは、ゼロからRailsアプリケーションを作れるスキルよりもまず、既存の「大きくて複雑な」Railsアプリケーションの仕様や構成を理解し、素早く機能追加や不具合修正できるスキルになります。

## 納期がある

受託開発にせよ、自社開発にせよ、多くの場合「いついつまでにこの機能を作ってリリースしてほしい」という期日とともに開発タスクが降ってきます。
学習用のプログラムを作るときはいくらでも時間を費やせるかもしれませんが、仕事でコードを書くときはそういうわけにはいきません。

高度なプラグラミングスキルを求められることはもちろんですが、それだけでなく「与えられたタスクを細かく分解して、ひとつずつ潰していけるスキル（タスクばらしのスキル）」や「困ったときにうまく人に頼るスキル（質問力・相談力）」も大事になってきます。

## ドメイン（事業領域）の知識が重要になる
学習用のプログラムは言語やフレームワークの使い方を学ぶことが目的なので、特定のビジネスに関する知識は不要です。
また、自分でポートフォリオを作るときも、自分が作りたいものを自分の裁量で決めるため、ポートフォリオを作るために必要な知識はほぼ自分自身の中にあるはずです。

ですが、仕事で書くプログラムは自社開発であれ、受託開発であれ、何らかの事業を実現する手段として開発されます。
もしあなたの就職した会社が町のパン屋さんを支援するシステムを作る会社だったのであれば、パン屋のドメイン知識（＝パン屋のビジネスモデルや、パンの製造工程、パン業界の専門用語など）を把握しておかないと、プログラムの仕様を理解したり、仕様の妥当性を判断したりすることが難しくなります。
逆にいうと、ドメイン知識があればあるほど、スムーズに開発が進められます。

元パン屋さんがパン屋のシステムを開発する会社に転職すればこのハードルは簡単にクリアできますが、そうでなければ技術的な知識だけでなく、その業界のドメイン知識もあわせて学んでいく必要があります。

参考資料：事業知識を深掘りし、より人の役に立つサービスに改善する
<script async class="speakerdeck-embed" data-id="8ddbd9e0fb4246b6b3bfa78b9595eb49" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>

## セキュリティを考慮する必要がある

学習用のプログラムは基本的に自分のローカルマシンの中でしか動かしません。
ポートフォリオとしてWebアプリケーションをインターネットに公開することはあっても、そのアプリでお金を稼いだり、そのアプリが何千〜何万というユーザーに使われたりすることはおそらくまれでしょう。

ですが、仕事で書くプログラムは不特定多数のユーザーからアクセスされます。その中には悪意を持ったユーザーが紛れ込んでいる可能性もあります。

セキュリティを考慮しないアプリケーションはあっという間に乗っ取られて悪用されるかもしれません。

## パフォーマンスや同時アクセスを考慮する必要がある

学習用に作ったプログラムの利用者は自分一人か、せいぜい数十人で、データベースに保存されるデータも大した件数にはなりません。

ですが、仕事で開発するシステムはデータベース上に百近いテーブルがあり、テーブルによっては何百万〜何億という件数のデータを抱え込んでいる場合もあります。
そんな要件があるにも関わらずパフォーマンスに問題を抱えたプログラムをリリースすると、ローカル環境ではさくっと問題なく動いていたのに、本番環境では何十秒も待たされることがあります。

また、仕事で開発するシステムは1秒間に何十〜何百というアクセスが発生するWebアプリケーションかもしれません。
そうなるとパフォーマンスが大事になるだけでなく、複数のユーザーが同じデータを更新するようなケースも考慮に入れる必要が出てきます。（人気アーティストのコンサートチケットを販売するWebサイトを想像してみましょう）

## システムが停止すると大金が失われることもある
Amazonや楽天のような巨大なECサイトは常時大量の注文をさばいています。
そこまで大きなサイトではなくても、システムの要件によってはそのシステムが数分間停止するだけで何百万円もの損害が出てしまう、というケースがあるかもしれません。
金銭面だけではなく、不具合を出すと人命に関わるようなシステムも中にはあるでしょう。

学習用のプログラムではまずそんな考慮は必要ないはずですが、仕事で開発するシステムはそういった責任を常に意識しながら開発する必要があります。

## だからこそ自動テストが重要になる

学習用のプログラムを書いている間はなかなか自動テストのありがたみを実感しにくいと思います。
おそらく多くの初心者プログラマが「テストコードを書いている時間があれば、手と目で動作確認した方が速い」とすら感じていることでしょう。
ですが、仕事でプログラムを書いているときは自動テストが必要不可欠になります。

なぜなら自動テストをしっかり書いておけば、人間の手と目では絶対に追いつけないスピードで「大きくて複雑な」システム全体の動作確認を行ってくれるからです。
何かおかしなコードを書いてプログラムが壊れてしまったときは、自動テストが失敗して不具合が起きていることを教えてくれます。

また、学習用のプログラムに比べて仕事で書くプログラムは寿命が長いため、一度作った自動テストは何百回、何千回と繰り返し実行されます。
自動テストを流す回数が数回だけであれば手と目でテストした方が速いかもしれません。
ですが、何度も繰り返し実行するのであれば多少工数を掛けてでも自動化した方が確実にトータルの開発工数を削減できます。

仕事でプログラムを書き始めると、その膨大なソースコードを前に「これは手と目でいちいち全部テストしてられんわ！！」とすぐに気づくはずです。
自動テストが大事なのはそういう理由があるからです。

ちなみに、自動テストの必然性については以下のスライドでも説明しています。

<script async class="speakerdeck-embed" data-id="501fcf00c8c840f59b0edb52b1c41808" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>

## どうすれば仕事でコードが書けるレベルになるのか

綺麗なコードを書くテクニックを学ぶのであれば、「[リーダブルコード](https://amzn.to/3m4PoPY)」や「[リファクタリング](https://amzn.to/3m2HBlS)」といった書籍を読むことである程度学ぶことができます。
とはいえ、個人的な経験からいうと、実務未経験の状態で読んでもあまり頭に入らないと思います。
現場に入り、半年か1年ぐらい経って「あー、これはきれいなコードを書かないと、カオスになるだけだわ」と実感したあとの方が、理解しやすいのではないでしょうか。

しかし、結局のところは「習うより慣れろ」の精神で巨大なコードにもみくちゃにされながら、必死でコードを読み書きした経験を積まないと、なかなか業務レベルのプログラムに太刀打ちできるスキルは身に付かないかもしれません。

僕がメンターをやっている[フィヨルドブートキャンプ](https://bootcamp.fjord.jp/)では、前述のEラーニングシステムを実際にスクラム開発するプラクティスが組み込まれているので、実務に就く前に業務レベルに近いコードを読み書きする経験をいくらか積むことができます。
プログラミングスクールでコードの書き方を勉強したいと思っている方は、こういったプラクティスが用意されているかどうかもスクール選びの観点に含めることをお勧めします。

## おまけ：プログラムとジェンガのメタファ

学習用のプログラムと仕事で書くプログラムはジェンガに例えられるかもしれません。

![Jenga_distorted.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7465/123a46de-7598-400e-46ae-7dd857d185c4.jpeg)Image: https://en.wikipedia.org/wiki/Jenga#/media/File:Jenga_distorted.jpg

学習用のプログラムは自分一人で遊ぶ背の低いジェンガです。
ジェンガを触るのは自分一人だけですし、背が低いのでめったなことで倒れません。

しかし、仕事で書くプログラムはその何十倍、何百倍もの高さを持つ背の高いジェンガです。
しかも、自分一人でなく、他のチームメンバーと一緒に積み上げていく必要があります。
下手な積み方をすると、すぐにぐらぐらとバランスを崩して倒れてしまいます。
よって、バランスが崩れないよう、「しっかり安定させながら、きれいにブロックを積み上げていくスキル」を身につける必要があるのです。
これは一人で遊ぶ背の低いジェンガではなかなか習得できません。

## まとめ：とはいえ、基本は大事！
ここまでさんざん、学習用のプログラムと仕事で書くプログラムは違う、という話を書いてきましたが、じゃあ学習用のプログラムを書くスキルはまったく役に立たないのかというと、そんなことはありません。

むしろ、学習用のプログラムをきっちり書けるスキルがあってこそ、仕事でもちゃんとしたプログラムを書くことができます。
学習用のプログラムすら書けない人が、仕事でバリバリきれいなコードが書ける、なんてことは500%ありえません。

なので、現在プログラミングを学習している人はそのままがんばって学習を続けてください。
この記事で言いたいのは、「学習用のプログラムが書けるようになった → だから、就職したらすぐにバリバリコードが書けるようになる」とは限らない（むしろそれだけでは厳しい）、ということです。

逆に、「就職したあともさらに高いハードルが待っているんだな」という心の準備ができていれば、就職しても自分のできなさ具合にそこまでショックを受けずに済むかもしれません。
まあ、大丈夫です。僕だって、最初からバリバリコードが書けていたわけではないですが、ひいひい言いながらコードを書いているうちになんとかここまで来れました。

ここに書いた内容がこれから就職を目指すみなさんや、新人プログラマのみなさんのお役に立てば幸いです😃

### あわせて読みたい

フィヨルドブートキャンプで生徒さんのコードレビューをしているときによく差し出すリンク、ベスト3です。
いずれも「プログラムは動くだけではダメ、プロの現場ではこうした配慮も必要」という観点で必要になる知識です。

- [モデルやメソッドに名前を付けるときは英語の品詞に気をつけよう \- Qiita](https://qiita.com/jnchito/items/459d58ba652bf4763820)
- [プログラミング初心者は変数名やメソッド名を略さない方がいいよ、という話 \- give IT a try](https://blog.jnito.com/entry/2020/10/20/092724)
- [（あなたの周りでも見かけるかもしれない）インスタンス変数の間違った使い方 \- Qiita](https://qiita.com/jnchito/items/49fe82364bca2f4f37f5)

https://twitter.com/jnchito/status/1376338002901827587

**2020-4-30 追記**
実際に開発タスクをアサインされたときに、どうやって「めちゃくちゃ背の高いジェンガ」と対峙すべきか、とその心構えと対応手順をまとめました。こちらもあわせてどうぞ。

https://qiita.com/jnchito/items/017487cd882091494298