カルテットの開発部には、10月から新メンバーが加わりました。新メンバーには、将来メインのプロダクト開発にガッツリと参加してもらうことを期待しており、それに向けた教育の一環として、設計力を伸ばしていくための土台づくりを行っています。この記事では、私が現在行っている新人プログラマー向けの教育を、どのような考え方で行っているのかを紹介します。
前提
今回対象としている新人プログラマーのスキルは以下のようなレベルです。
- Webサイト制作的な案件を一人でこなせる
- オブジェクト指向プログラミングについて、書籍などを読み一定以上の知識を持ってはいるが、実務において深く活用したり、他人と意見交換した経験はない
この記事で扱っている「設計」は、プログラマーが行うコードの設計、およびコード群の組み合わせ方の設計といったあたりまでを指しています。
また、この記事では、設計の中身(どのような設計が良いのか等)の教育についてはほとんど触れていません。
設計は学びづらい
設計というのは、プログラマーのスキルの中でも学びづらいものの筆頭です。多くの方が、設計について学ぶのに、何かと苦労されているかと思います。そのような苦労からか、いつしか「設計力を身につけるには、とにかく現場での場数が必要」と考えるようになってしまっていないでしょうか。私も過去に、そんな考えにとらわれていた時期がありました。ところがある時、見習いプログラマーから次のように質問され、ハッとします。
「現場で場数を踏みさえすれば、必ず一人前の設計者になれるのでしょうか?」
あなたがこの見習いプログラマーの教育担当だったら、どう答えますか? 「バカヤロー! そんな事を聞くのは10年早いわっ!」などと怒鳴りつけるわけにはいきません。一人前の設計者らしい鋭い洞察力が滲み出る回答をしたいところです。もちろん、質問への回答は「NO」です。ただ場数を踏めばよいだけなら、それはそれで大変ではありますが、学ぶこと自体に苦労はしません。つまり、単に「場数を踏む」ということ以外に、必要なことがあるのです。それは、1回1回の場数を踏んでいく際の「場数の踏み方」なのです。場数の上手な踏み方を身につけていないと、どれだけ場数を踏んでも全く成長しません。成長したとしても、とてもゆっくりとしたものになってしまうでしょう。しかし、場数の踏み方が上手な人は、少ない場数でも確実に成長していけます。
プログラマーの日々のコーディングの中で、変数やクラスの命名、きれいなロジックへの修正といった、小さな設計行為は多数行っているものです。しかし、判断に数日迷うような設計、様々なことを調査して比較しなければいけないような設計、一見太刀打ちできなさそうな複雑な問題に対する設計といった大きなものもあります。このような設計こそ設計力が試されるので、設計力を伸ばすチャンスでもあります。しかし、大きな設計問題は頻繁に出てくるわけではありません。したがって、そのような問題から学んで成長するには、少ない場数で確実に学びとる力が大切なのです。
また、プログラムの設計という活動では、フィードバックまでのタイムラグが長くなりがちです。このことも設計の学びづらさに関係していると私は考えています。何かを学んで身につけ磨きをかけていくには、自分の行為がどのような結果をもたらしたのかというフィードバックを受けて、次の自分の行為に改善を加えていくというサイクルが欠かせません。しかしプログラムの開発では、何か設計を行っても開発しただけで終わってしまったり、または、数ヶ月後の機能追加や仕様変更などといったタイミングで、ようやく過去の設計と向き合うことになるといった形が普通です。自分の設計に対して評価するのは、設計を行ってから随分と時間が経った後のことになってしまうのです。このようなチャンスが幸運にも巡ってきた時に、確実に学びを得る力が必要です。
では、少ない場数でも確実に学びを得るための、土台となるスキルは、具体的には何なのでしょうか。
設計力を伸ばすための土台となるスキル
設計力を伸ばすための土台となるスキルは、「論理的思考力」です。これは、たとえば以下のような力のことです。
- 物事を、何らかの観点で分類・整理する力
- 論理的に筋道を整えて主張を述べる力(論証力)
- とりうる立場を複数検討し、それぞれの立場から見る力(批判的思考力)
論理的思考力は、プログラマーの仕事において、与えられた問題に対する分析や解決方法の構成に役立つのはもちろんです。しかし、今回注目したいのは、それとは少し異なる側面です。論理的思考力があると、問題の分析や解決方法の構成に至る道筋が、とてもはっきりとしたものになります。そうすると、時を経てその分析や解決方法の結果に対するフィードバックを得た際、最初に立てた道筋のどのポイントが結果に影響を及ぼしていたのかを把握することができます。その結果、フィードバックを的確に改善につなげることができるのと同時に、フィードバックから確実に学びを得ることもできるのです。
ただし、論理的思考力だけでは車の片輪でしかなく、プログラムの設計力の土台として有効に活用するためには、もう片方の車輪が必要です。それは、技術面の知識です。なぜでしょうか。どれだけ論理的思考力が鋭くても、技術面の知識が乏しければ、精緻な技術的検討・論証が行なえないのです。プログラム設計一般に関する知識、利用するプログラミング言語の言語機能に関する知識が伴うことで初めて、眼の前にあるプログラムコードの設計の機微が語りうるものとなるからです。
したがって、プログラムのコードを題材として、論理的思考力を養うようなトレーニング というのが、私が新人向けの設計力の土台作りとして行っていることになります。例をいくつか紹介します。
トレーニング内容の例
以下のトレーニングは、実際の業務のプロジェクトではなく、練習用のプログラミング問題を解くことを通して実施しています。そこでは、形式的なゴールは「問題を解くコードを作成する」ことですが、ゴールへ向う過程で、論理的思考力を養うトレーニングを同時並行で行います。そのために、問題を解くコードを一気に完成させることはせず、TDDのようなスタイルで、問題をいくつかの部分に分割(これも新人プログラマー側が考える)し、Issueやプルリクエストで事細かにやり取りをしながら、少しずつ進めていきます。
名前付けの理由を説明するトレーニング
このトレーニングでは、設計案や実際にプルリクエストで出されたコードに登場するクラス名、変数名、メソッド名、テストケースの名前といったすべての要素に対して、なぜそれを選んだのかという理由を求めます。また、プログラムにおいて重要な役割を担うクラスやメソッドについては、他の候補がなかったか、他の候補と比較して良いと考える理由も求めます。
また、コードに使ったクラス名や変数名を使って「何をやっているのかを説明する」ということも行います。
このトレーニングを通じて、「問題を捉えて、それをコードに表現する」というプログラマーが自然に行っている活動に自覚的になり、「頭で認識した問題の構造」と「表現されたコード」との間のギャップに敏感になるよう促していきます。
仕様変更対応トレーニング
このトレーニングでは、新人向けに出しているプログラミング問題を、段階的に仕様変更していきます。例えば次のような仕様変更を行います。
- 入力値の与えられ方の別仕様
- 結果の表示の仕方の別仕様
- 問題の解き方における別ルール
- 大きなデータ量への対応
ポイントは、仕様変更によって、最初に実装したコードの設計に対して強制的にフィードバックが入ることです。フィードバックを頼りに、最初の設計のどの部分が良い働きをしているのか、逆にどの部分が良くない働きをしているのかを考えます。といっても、新人プログラマーにいきなりそのような事を見抜くことはできません。この段階の場合は、教育担当者が新設計の案の作成を誘導しながら行っていき、上手くいく形の設計に仕上げて行きます。それが出来上がった後で、変更の前後を見比べて、仕様変更のどの部分が、コード変更のどの部分と対応しているのか、ということを後追いで検討します。
このトレーニングを通じて、自分のコード設計に対する批判的な態度を養います。
おわりに
いかがでしたでしょうか。
論理的思考力のような基礎スキルを養うトレーニングは、即効性のあるものではありません。しかし、年単位のような長い時間軸に目を移した時、人の学びを加速する起爆剤といってもよいほどの効果があると思います。この記事に書いた活動は、実際にはまだ始めたばかりで、どのように実を結ぶのかは分かりませんが、新人の成長などを通してフィードバックを得て、この土台作りのコンセプト自体も磨きをかけていきたいところです。
設計について学んでいきたい若手エンジニアの方、そして新人プログラマー向けの教育に関わっている方の参考になれば幸いです。