プログラミングの階段を登る方法をまとめた

初めましての初投稿です。
新人の方も新しいチームに配属されて数ヶ月、「どうしたらプログラムが書けるようになるんですか？」と聞かれることも増えました。
「プログラムを書ける」と一言でいっても人によって、いろいろな段階があると思います。成長を感じながらプログラミングの成長階段を上がっていくにはどうすれば良いかを、色々な人と話しながらまとめてみました。
プログラムは書ける人ばかりじゃないし、書けないままの人もいるんです。自分のペースで階段を登って行きましょう。
本記事は主にオブジェクト指向言語を対象としています。

#　プログラミングには階段がある
極端に言うと、プログラムを書くという作業は文法さえ覚えればかけます。文法を何回見ても意味が理解できないという方はあまりいないと思います。
そういう状況で「私はプログラムが書けない」と感じて足踏みしてしまうポイントは、以下などではないでしょうか。

1. すでにあるプロダクトのコードを読もうとしても、ある一定の深さのところまでいくと追えなくなる
1. 簡単なものを作ろうと思ってもモデルを作ったところで、次に進めなくなってしまう

## 階段の踊り場でよく見られる状況
これらはどんな人でも感じる「あるある」ですし、実際の現場でも見かけることが多いです。
文法だけを覚えて、開発現場に投入されるとトランザクションスクリプトパターン[^1]の中でしかプログラムが書けないプログラマーとなるのは必然です。
どういうことかというと、文法を知っているだけのレベルで現場に入るとStruts全盛期のいわゆる「Action職人」のように、アプリケーションの決められた箇所に業務処理を手続き型で実装するスキルセットしか持つことができなくなります。この状態では自分の実装箇所以外の処理内容は知らないし、理解することもままなりません。
なお、この労働集約的な手法一辺倒で作られたソフトウェア(労働集約パターンと名付ける)は、機能追加や障害対応に非常に脆いです。さらに良くないのはそういう環境で育つとそれを当たり前と感じ、それ以上のプログラミング学習をやめる一因となることです。学習をやめてしまったら、その人は自分の知っている労働集約パターンでしかプログラミングができないだけでなく、それを押し付けてしまうダークサイドに入ることでしょう。アンチパターンなSEとしてよくネタに上がるタイプですね。そういう人を見かけたら、本記事を紹介してあげてください。

## 踊り場からは順に上がっていくしかない
では、どうすれば足踏みせずに、 「プログラムがかける」 という自信をもつレベルに到達することができるのでしょうか？以降でJava、C#、JavaScriptなどのオブジェクト指向型言語の習得を想定して、その成長を4段階にわけて整理してみます。ちなみに私自身は１，２，３はまずますで４は研鑽中ぐらいかなと思います。

[^1]: [トランザクションスクリプト](http://bliki-ja.github.io/pofeaa/TransactionScript/)

# プログラミング成長の4段階(オブジェクト指向言語)

## １．文法を理解して、書籍通りになぞってみる
### 完璧主義は捨てましょう
この状態は外から見れば、「プログラムを書いている」という風に見えるでしょう。ただやっている本人は「なんか写経しているだけで自分でアプリケーションを作るなんて無理」と思う人が多いと思います。
多くの人が躓くのは、c#でいえば、インターフェース、ジェネリック、ラムダ式、LINQなどの部分だと思います。
このあたりは、後で記載する段階3と4の理解でスパイラル的に理解が深まるので、まだここで挫折感を感じるのは早計です。誰でも通ってきた道です。
この段階では写経して、書籍によくある章末の問題が何問かは解けるという程度でよいと思います。章末問題については出題者は読者のレベルを正しく理解しているわけはないし、その問題を解くために必要なバックグラウンドは人によって異なるので「全問できないから、私はもうだめだー」という完璧主義は早めにどこかにおいてきたほうがよいです。
いずれにしても、文法の勉強は期限を決めて行うことが大事で、いつまでも続けることはやめたほうが良いと思います。長くても2週間から1ヶ月程度と思います。
### 初めてでもコードは綺麗に書くように留意しよう
この段階で行う写経やそれを少し応用したアプリケーション開発を進めていく上での注意点を記載します。
・クラス名、メソッド名や変数名などはできる限り注意して、きれいに書くことを強く意識してください
・リーダブルコードなどきれいに書くための書籍も併読することをおすすめします
書籍やネット上のサンプルコードが必ずしも正しいわけではありませんので、Visual StudioやIntelliJのコード分析機能やEclipseのSonarlint/FindBugs/PMD/CheckStyleを使用してチェック(静的解析)を実施する習慣をつけてください。
なによりもきれいなコードを書いておかないと基礎的なアプリケーションとはいえ、1か月たつと自分でも何書いていたかわからなくなって、プログラミングを遠ざけてしまうきっかけとなります。

## ２．ライブラリを活用して、何かを作ってみる
### クラウドがあれば今は動くものが作れる
ステップ１の状態でもライブラリや外部サービスを組み合わせてアプリケーションを作ると、ある程度動くソフトウェアを作ることができます。
クラウドを利用すればサービスとして提供するものさえ開発することができてしまいます。
今日ではクラウドのサービスを利用すれば、「プログラムがすごい書ける状態でなくても、アプリケーションを作れる」というのは間違っていません。

### 動くものができたけど不安なのは、プログラミングスキルのせいではない
ただ、この状態でも「動くものは一応作れたけど。。」という不安は解消されていないはずです。
この不安の最大の理由はこの後に記載する４の段階に至っていないことが理由と考えます。
デザインパターンといっても広義ですが、MVC,MVVMなどのアーキテクチャパターンなどを理解することでアプリケーション開発として必要なことを押さえることができ、不安も徐々に解消されていきます。
とはいえ、まずは動くソフトウェアを作ることは自分の現在の状態を明らかにしてくれます。
この第2段階で難しいと感じる場合、それはコーディングの能力が不足しているのではなく、WEBやデータベースアクセス、クラウドに関する理解の不足の可能性があります。まずは、不得意と感じる分野の基礎を書籍などで調べて基本的な動作を理解することを先に進めることが近道になると思います。
調べながら、ライブラリを活用していくことでアプリケーション開発の標準スキルはいつのまにか大きく向上していることでしょう。
次はオブジェクト指向だ！という感じで、文法学習の後にオブジェクト指向の学習に進む人もいるかもしれませんが、まずは動くアプリケーションを作ってみることをおすすめします。その後、オブジェクト指向でリファクタリングするという順序が、継続していく上でもよいモチベーションになるかと思います。

## ３．オブジェクト指向で設計と実装を行う
### 手続き型プログラミングからの卒業が必要
この段階からプログラミングが苦手と感じる人にとって最大の壁になるのではないかと思います。
継承、ポリモーフィズム、カプセル化のテクニックを使用したアプリケーションに出会ったとたん、プログラムが追えなくなる。もしくは、そういうアプリケーションに対する正しい機能追加の設計ができなくなるということを感じた人はたくさんいると思います。
インターフェースに対してプログラミングするとか、is-aやhas-aの関係性を理解しておかないとここの壁は簡単に超えられません。しかし、ここは自分一人で乗り越えるよりも、誰かすでに知っている人にコードを書きながら説明してもらうと意外と簡単に超えられます。実際簡単なものではないので、臆せず人に聞いて前に進みましょう。
### 自分のコードをリファクタリングしよう
オブジェクト指向を理解するための近道はペアプログラミングだと思います。しかし、周りにそういう方がいないというという場合は、自分が作った過去のコードをSOLIDの原則に沿ってリファクタリングすることで、オブジェクト指向の効果や意味がわかってくるようになると思います。

## ４．デザインパターンを知って活用する
### アプリケーションアーキテクチャを書くにはまだ不安がいっぱい
オブジェクト指向をある程度理解すると、コードを読んだり、書いたりすることが大分できるようになります。おそらく、本番製品のコードを改修することも簡単にできると思います。
ただ、その状態ではアプリケーションの新規構築や複雑な業務処理の実装にはまだ不安な点が残っているんじゃないかと思います。
### デザインパターンで先人の知恵を活用しよう
それを超えるためのツールがデザインパターンです。データベースアクセスの設計や、業務処理の分割方法などデザインパターンにはそれを効果的に行う知恵が詰まっています。
正しいオブジェクト指向、デザインパターンを適用されたアプリケーションは理解しやすく修正が容易という利点もあります。何より、後から入る人に説明をする手間が大分減るという効果もあると思います。
ただ、デザインパターンは世の中に無数に存在します。オブジェクト指向のためのSOLIDの原則、GoFデザインパターン、そしてUI実現のためのMVCやMVVMなどのアーキテクチャパターンなど幅広いです。
多いけど嫌にならないでくださいね。(どれからやればいいかは目的次第ですが、まずどういうものがあるかを理解することが犬の道にならないと思います。)
デザインパターンがある程度わかるようになれば、プログラムを書くのが楽しくてしょうがない状態になっていると思います。
労働集約パターンなアプリケーションを見ると、リファクタリングしたくてたまらないでしょう。
### ４つの段階は繰り返し行う
コーディング学習、ライブラリを使って動くものを作る、オブジェクト思考、デザインパターンを使用したリファクタリングはそれぞれを長い時間費やすのではなく、短い期間で繰り返すことでより理解が深まります。ぜひ、期間を決めて取り組んでください。


# 学習でやってしまうあるある
上記の学習ステップを踏まえて、個人的に考えるまれに初学者がやってしまう、もったいないことを2点書きます。
## 最初に出会った1冊目の文法を覚える本の学習に何か月も費やす
　おそらくプログラムの理解で難しいと感じているところの多くはオブジェクト指向や関数型プログラミングに関する部分です。その本にそれに関する記載が不足していればいつまで読んでも苦手意識は消えません。本を変えてみましょう。
そして、上記の4段階で説明したように文法だけ理解しても、オブジェクト指向言語を自信をもって使いこなせるという境地にはたどり着けないので、いつまでも同じ文法本を大事にせず、違う本やアプリケーションの開発に進んでみましょう。
## 古い本を使っている
　C#の学習にありがちなのですが、Version 3やVersion 4をベースに記載された翻訳本を読んでいる人を見かけます。全く意味がないわけではありませんが、「古いけどAmazonで評価が高い」という本に盲目的になるのはよくないと思います。(最新だけを追うというのも同じようにあまりよくないと思いますが)
　ただ、あえてこれに反した書き方をしますが、「Effective Java 2nd edition」は古い本ですが、上記で書いた段階３，４の部分を押さえた本ですので今でも読む価値はあります。ですので、文法学習に古い本をどうしても使いたい場合は、それに加えて、新しいバージョンの仕様が記載された本も購入して読むことをおすすめします。

## Java及びC#で文法本の次の本としての私のおすすめ
最近の言語仕様を押さえて、３、４段階に進むためのおすすめ本は以下です。

- Java
[Java本格入門 ～モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで](http://amzn.to/2itptoh)
- Java 
[アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技](http://amzn.to/2irLtQo)
- C#
[実戦で役立つ C#プログラミングのイディオム/定石&パターン](http://amzn.to/2irNCM7)