技術に対する理解をしながら技術開発を爆速で終わらせるフレームワークの提案
※(2019/05/13追記)自己愛が強い時代に執筆したものなので、文章が冗長でしかもわかりにくいです。近いうちに推敲なり記事を分けたりしながらリファクタします。
1. 背景
僕がエンジニアになろうと思ったきっかけは、自分の考えているサービスを形にできる技術力が欲しいと思った点、エンジニア自体に需要があるためこれから給与が上がっていく点、技術力があればリモートで働くことが比較的容易なため、自由度が高く子育てなどがしやすい点がある。
そういったきっかけから2018年の4月にエンジニアの道を歩んで早10ヶ月が経とうとしている。
自由に仕事がしたい
早く成功したい
もっと早く技術力をつけて稼げるようになりたい
といった脳内の空想と、エンジニアとして独立して食べていける技術力が付いていないというリアルな現実にギャップが生じている。
つい数ヶ月前までのボクの開発における思考回路はこうだ。
システムがどういう順番で動いているかも分からないし、ソースコードをどう変更したらいいか分からないから、ここだろう!と適当に変数を変更してどう動くかを運否天賦で判断する(本人は至って真面目)。
エラーが起きたら基本はパニクる。エラー画面にお前はダメなやつだ!と宣告されているような気持ちになるし、<>\=#のような記号を含む英文の塊がこれでもかというくらい圧力をかけてくる。
中肉中背だけど色黒で声が大きくて、気に入らないことがあったら癇癪起こしてナイフで刺してきそうな、神経質なクレーマーに大きい声で怒鳴られてる。そんな感覚に近い。
どういう順番でどのような原因でエラーになっているのかも分からない(しかも英語だから読むのを躊躇う)。かといって下手に変なところを動かしてしまったらさらにエラーが起きてしまって、ソースコードを壊してしまうのではないかと思いビビる。
データベース周りでは消したデータが二度と戻ってこないという噂があるので尚更だ。怒られるのは嫌だし、場合によっては直し方も英語で書かれているため説明が腑に落ちない。
結果、よく分からない壊れた文字列の羅列に触れることが怖くなってしまい、簡単なエラーでも時間がかかってしまう。
しかし、早く技術力を身につけリモートとかで仕事がしたいし、プロダクトをEXITして成功したい。なので、職場の金食い虫では困るし、しっかりと技術で貢献をしたい。
プロとして製品を納品するための具体的な業務の流れとして、①システムがどう動いているかを把握し②ソースコード毎のメソッドがどのような役割をしているのかを把握し、③エラーが起きたとしても焦らずバックトレースなどを読んで原因を把握しつつ順を追って解決すること。
かつ、④業務で学んだ知識を再現性のある形でまとめ、他の現場や自身の開発の際にいつでも使えるような形にまとめておく必要がある(丁度自作のライブラリを使うような手軽さで)。そして、①〜④の開発業務の流れを血肉にすることが大事だ。
しかし、今はまだまだプログラミング初心者。変化の早いIT業界かつ、分からないメソッド、エラー、ミドルウェアの使い方が次々と初心者に襲いかかってくる現状で、①〜④の概念を状況に応じて瞬時にスイッチングしながら作業するのはワーキングメモリーの観点からいっても厳しい。パニクって状況が悪化するのがオチだ。
したがって、①〜④の 業務から理解までの流れを1枚のA4用紙に一目見てわかるようにマニュアル化し、考えること(=ワーキングメモリーの稼働数)を減らし、より生産的な活動に注力するためのフレームワークが必要だと考えた。
2. 目的
技術に対する理解をしながら作業爆速で終わらせ、爆速で成長する学習フレームワークマニュアルの作成。
これを行えば
①ワーキングメモリーを消費しなくて済むのでより生産的な行動ができる。
②初心者が作業の順序を把握することで、エラーが起きた時などでもテンパらずに作業の時短ができ、効率よく成長できる。
③コーディングとデバッグのスイッチングが容易。
④フレームワークが文字だけではなく図にもなっているため、一目見て分かりやすく把握しやすい。
⑤自分のやり方を確立し、体調に左右されず、出力が低い時でもコンスタントに結果を出すことができる。
⑥ 自分の業務のやり方が開発哲学として一本筋で通っているため情報が濁流のように流れてきて自分を見失いそうになった時にも安心感がある。同時に、有益そうな情報に右往左往して結局何も身についていないという状態を阻止しつつ、自分に必要な情報を適宜柔軟に取り入れることができる。
という利点がある。
3. 調査
エンジニア歴1年未満のペーペーがゼロからマニュアルを作ることはできない。
マニュアルを作るためには、先駆者の思考を奪うことが肝要だ。そのために周りで働いてるエンジニアやqiitaのバズ記事や影響力のありそうなエンジニアがどういう思考でコーディング作業しているかの情報を砂金を集めるかのように掻き取っていかなければならない。
砂金を抽出し、そこに宿る「コードの読み方」「コードの書き方」「デバッグの方法」といった作業それぞれの本質をA4 1枚に統合しマニュアル化する。
すると、途中からプロジェクト参画をする時に「やんやん♡プロジェクトに入ったけど何したらいいか分からない〜」という状態から「今はこのプロジェクトに入ったばかりだから全体を把握しよう。まずは仕様書とソースコードを見てみよう!」という具合に思考が変わるし、
コードを読み書きする際にも「なんとなく本の通りにコピペや写経してみた」という状態から「クライアントからのリクエストでクッキーに入っているパラメーターを持ってきて、それをコントローラー内で処理をして…」というコンピュータの処理の流れを論理的に理解する思考に変わる。
最終的に、A4 1枚の紙で「コードの読み方」「コードの書き方」「デバッグの方法」等々の、個々のトピックも含めた開発作業全体の大きな流れを鳥瞰しながら具体的に理解できるようになる。徒手空拳で霧の中を彷徨っていたプログラミング初心者にとってのそれは目の前の霧が晴れ、地図とコンパスを渡されるようなものなのだ。
フレームワークを使い、不確実性の高い歩みを少しでも確実にし、力強く歩みたい。
そのため、この1年でいろんな文献を読みながら実務に触れ、先輩エンジニアのご指摘やデバッグの際にどういった思考をしているかを初心者と比較をして分析してみた。
3.1 順序
コーディングやエラー対応を見てもらったりしている際に、
「クライアントからのリクエストでparamに入っている値を持ってきて、それをコントローラー内で処理をして…」
「ここでデータベースにアクセスして、値を持ってきて、viewに返す挙動になるようにコードを書こう」
「エラーが起きた。じゃあまずはバックトレースをみていこう。…この辺が怪しいから、この行にブレークポイントを打とう。」
のような話をされる。このことからプロは「コードの読み方」「コードの書き方」「デバッグの方法」それぞれの順序を把握して作業をしていることがわかる。
師曰く、プログラミングは徹底した論理の積み重ねであり、まずはその流れを理解しないことには始まらないからだ。
したがって、まずは「コードの読み方」「コードの書き方」「デバッグの方法」それぞれの型というか、順序を整理しまとめる必要があると考えた。
3.2 ストック
エラーが起きた時やある機能を実装したいときにその方法が分からない時がある。頑張ってもできない。その際に藁にもすがる思いで話を伺うと、
「これこのメソッド使えばいいんじゃない?」「〜するには色々方法はあるけど…自分の好きな方法でやってみて」
「エラーになる方法は〜〜と〜〜と〜〜と……」「このエラーはデータベースに問題がありそうだね!」
のような話をされることが多かった。プロはハード・ソフト両面における膨大な基礎知識はさることながら、エラーに対する原因の洗い出し・解決法のストックがとにかく多いのだ。
これは3.1で「コードの読み方」「コードの書き方」「デバッグの方法」のそれぞれの順序を理解するだけでは不十分で、私がこの"問題に対する解決法のストックの多さ"がいわゆる"実務経験"と言われるものであると考えた。
初心者:ストックがないから右往左往するし、すぐに分からなくなるし不安になる。ちなみに原因は2つしか浮かばない。
プロ:初心者が思いつかない(プロは簡単に思いつく)ような原因が100個くらい浮かび、それをエラーコード読んだり挙動を見て原因を絞っていく
のような具合だ。
またこのストックと呼ばれるものは、前者の例のような「ライブラリや頻出するメソッドがの使用法」といった攻めの知識。後者の例のような「問題が起きても豊富な経験・知識で自己解決ができ、リカバリーが早い」といった守りの知識の2つが存在することがわかる。
そして、攻め・守り両面の知識を仕事の中でフレームワークに沿って効率よく、ストックという形で獲得することができればいいなと考えた。
そのために、ストックを効率的に集める方法を考える必要がある。
4. フレームワーク
上記2つの条件を満たした、学習フレームワークマニュアルを提示する。
(字が汚くて読めないと思うので、後日、イラレとかを使って分かりやすい図を作成します。)
学習フレームワークマニュアルは「コードを読む」「コードを書く」「ストックにする」の3つの段階に分かれており、行動の順序の整理、開発で得た知識のストック化による他プロジェクトでの転用後を可能にしている。
図を見ても理解はできるが、まずはそれぞれの領域の詳細について記載していく。
5 コードを読む
開発業務の8割はソースコードを読む時間と言われている。
8割なので素人とプロがどんな見方をしているのかの違いが如実に現れるので、業務のスピードや質に一番差が出てくるところでもある。
つまり、読むを支配する者は業務を支配するも同然ということなのだ。
すると、プロがソースコードをどのような視点で見ているかが気になった。
僕自身まだプログラミング初心者のフェーズ。あるプロジェクトに参画した時の話。右も左も分からない雛鳥なので、プロジェクトに入った1日目に何をすればいいかを先輩エンジニアに伺うと、「まず仕様書の理解をしよう」と言われた。10日後に同じことを聞いたらは今度は「ソースコードの内容の理解」しようと言われた。
このことから、「ソースコードを読むときはまずは全体を把握して、その後に詳細を把握するというステップを踏むことが重要」だと類推される。全体→詳細だ。
キャッチーな言葉で訳すと鳥の目 虫の目 魚の目で分けることが重要となる。(魚の目の内容が浮かばなかったので、魚の目に相当するものがあったらご教授頂けると幸いです!)
なのでコードの読み方としての鳥の目、虫の目を次項で詳しく説明する。
5.1 鳥の目
鳥の目を一言で言うと、
「コンピュータシステム上でのプログラムの順序を俯瞰しながら流れで追っていくことで、ソースコード全体の流れを把握する見方」だ。
全体を把握することによりエラーをした際に自分が今どこにいるのかを理解することができるので、相手にエラーを説明する際に「このファイルのこの場所でエラーが起きてます!恐らくDBの受け渡しに原因があるのですが…」といった具合に説明でき、質問に答える相手も把握しやすく説明できるというメリットがある。
鳥の目を攻略するには、「前提になるシステムロジックの理解」と「実際のプロジェクトでソースコードを鳥瞰的に理解する際のポイント」の2つの基礎知識が必要だ。中でも「前提になるシステムロジックの理解」は基本と経験の2つに分けている。図で表すとこんな感じ
それではまず、基本からやっていく。
5.1.1 前提になるシステムロジックの理解
①基本
コンピューターモデルの階層方式やクライアントサーバー方式やMVCモデルといった、プログラムの処理の流れの基本を理解する。
遊戯王でいうドローフェイズからスタンバイ、メイン、バトル、メイン2、エンドフェイズといったカードを操作する際の流れ。ルールを把握するようなもの。
これは実務経験がなくても理解しやすいため、鳥の目で理解する際に初心者がまず目を通しておくものでもある。
②経験
実務経験を通して、基本にはないタイプのプログラムの流れを経験としてストックしておく。型が決まっている分基本に近いが、デザインパターンなどは経験に位置するものだと考えている。
知識・経験をストックとして貯めていくことによって、プロジェクトごとのソースコードの類推を大量の知識ストックを用いることで容易にし、開発速度をより速めることができる。
これは遊戯王でいうリアルなデュエル。スタンバイフェイズにクリボーを生贄に捧げて、ジャッジマンを召喚。装備魔法、デーモンの斧を装備させて、そのままバトルフェイズでブルーアイズを破壊するといった具体的なカードの出し方や、ロードオブドラゴンとドラゴンの笛といったカードコンボの組み方に近い。。といった感じ。ルールに従ってカードを動かしていれば何をしてもいいといった具合。
5.1.2 プロジェクト内での理解
5.1.1 を前提知識として持ちながら5.1.2 プロジェクト内での理解をしていく。効率よく俯瞰するときのポイントとしては以下が挙げられる。
・システムの流れを知ってる人に聞く
・設計書を読む
・システムをブラウザから動かしてみる。リアルの動きからプログラムの動きを類推
・POSTしてきたデータがどう使われ、どう出力されるかをブレークポイント等を打って追ってみる
・変数名、メソッド名から使い方を類推する
以上、ビジネスロジックを理解しながら、プロジェクト内を上記ポイントを押さえながら読んでいくと全体の理解が早くなる。
全体を理解したら、次はissueの内容に応じてソースコードの詳細の理解をしたいので、それを虫の目でどのように見ていくかを把握していこう。
5.2 虫の目
虫の目を一言で言うと、
「コンピュータシステム上でのプログラムの具体的な動きを把握することによって、結果的にソースコード全体の動きを把握する見方」だ。
メソッドや変数がそのソースコード内でどんな風に使われてるかを理解したり、エラーの原因をそれぞれのメソッドの動きを鑑みながらピンポイントで突き止めるという目的がある。
なお、初心者の場合は該当する英語の羅列が単なる変数なのかメソッドなのか。メソッドの中でも組み込み関数なのか標準ライブラリなのか外部ライブラリなのかが分かっていない場合が多い。そのため、本番のソースコードを見て変数とメソッドの違いを秒で把握することはそれだけで労力を使うし、虫の目にはそういった違いを初心者が把握しやすいというメリットがある。
次項ではその「メソッドの類推方法」「変数の類推方法」を記載していく。
5.2.1 メソッドの類推
類推① ブレークポイントを打ちながらクライアント側の動きとサーバー側の動きを比較して、クライアントのどの処理がサーバー側の処理になっているかを類推する。
ex) 型変換するタイプ、文字コード変換、ファイルに書き込む、同じ列に追加するタイプ、例外処理するタイプというツールが何をしているのかを集める
類推② 英単語の意味から、どういうメソッドなのかを類推する。こういう動きをしているはずだ
類推③ メソッドは組み込み関数?標準ライブラリ?外部ライブラリ?それとも、自作クラスのメソッド?(これは初心者にとってわからない)
5.2.2 変数の類推
類推① 計算の答えを入れているパターン(x = 1 + 2)
類推② この英語名は〇〇な使われ方をしているという類推(fos→FIleOpenStream, opl→OutPutLine, getUserName→名前を持ってこようとしているんだな)
類推③ インスタンスを入れているパターン(user = User.new)
類推④ 配列を入れているパターン(for i = 1 to 3)
鳥の目と虫の目を駆使しプログラムの全貌を理解していくことで、コードを読む行為を効率的にし、業務の8割を支配できるようになるのだ。
6 コードを書く
開発の花形といえばコーディング&デバッグだ。同時に、開発もゼロからイチを作る作業であり、ストックや開発の型を知らない初心者は型に嵌めての理解が必要だと感じた。しかし、正直開発に関してはまだまだ弱いので、経験を通じて適宜追加をしていきたいが、現時点で理解している内容を列挙していきたい。
6.1 コーディング
コーディングではコードの効率のいい参照方法、コーディングルールの理解、アルゴリズムの理解の3つが必要だと感じた。しかし、コーディングルールの理解とアルゴリズムの理解をA4の用紙に記載しきれなかったので、コーディングルールなどに関してはリーダブルコード等を参照にし、今回は「コードの効率のいい参照方法」について列挙していく。3行だしMECEになってないが、コメント欄や経験を通じて今後もっと追記していきたい。
6.1.1 コードの効率のいい参照方法
・似た機能が別プログラムにあったら機能を理解した上でパクる
・ヘルパーメソッドも目を通し、機能を理解した上でパクる(開発時間との兼ね合いで、メソッド名から機能を類推し、出力値に問題がなければ荒いチェックでもOK)
・〜〜な機能を見てみたい!と思った際に、使われているであろう単語を検索して見つけ、機能を理解してパクる。
6.2 デバッグ
1.背景でも語ったが、僕はエラーが怖い。
エラーが起きたら基本はパニクる。エラー画面にお前はダメなやつだ!と宣告されているような気持ちになるし、<>\=#のような記号を含む英文の塊がこれでもかというくらい圧力をかけてくる。
中肉中背だけど色黒で声が大きくて、気に入らないことがあったら癇癪起こしてナイフで刺してきそうな、神経質なクレーマーに大きい声で怒鳴られてる。そんな感覚に近い。
どういう順番でどのような原因でエラーになっているのかも分からない(しかも英語だから読むのを躊躇う)。かといって下手に変なところを動かしてしまったらさらにエラーが起きてしまって、ソースコードを壊してしまうのではないかと思いビビる。
データベース周りでは消したデータが二度と戻ってこないという噂があるので尚更だ。怒られるのは嫌だし、場合によっては直し方も英語で書かれているため説明が腑に落ちない。
結果、よく分からない壊れた文字列の羅列に触れることが怖くなってしまい、簡単なエラーでも時間がかかってしまう。
背景で記載した内容を引用するが、心情としてはこんな感じだ。こわい。
しかし、早く技術力を身につけリモートとかで仕事がしたいし、プロダクトをEXITして成功したい。なので、職場の金食い虫では困るし、しっかりと技術で貢献をしたいのでデバッグ力は重要だ。
そこで、デバッグの際にどのように行動すればいいかをマニュアル化することで、エラーが起きてもテンパらずに順を追ってデバッグすることができる。
それではエラーが起きた際にどのように対処すればいいかを列挙していこう。
6.2.1 バックトレースを見て大まかな原因を把握
バックトレースを読むことで、どこのポイントでどんなエラーが起きているかが理解できる。分からなくてもバックトレースの中のエラーメッセージをコピペして検索すると、エラーの対処法について色々出てくる。エラー内容によってはそのままコピペ修正が可能なので、予想通りに動いたら開発に戻る。
しかし、大体の場合は検索した内容をそのままコピペしてうまくいくことなんてないので、ここではエラーになった事実を集めることで、その後の仮説を複数見据えることを目的とする
6.2.2 デバッガーを使って具体的にどこで詰まっているかを把握
ブレークポイントを打ち、1行1行F6で進んでいき、どこがエラーポイントかを把握。変数が入っているかを調べる(処理が動いているかどうか)
ここでもエラーになった事実を集めることで、その後の仮説を複数見据えることを目的とする。
6.2.3 FHAシートで事実仮説行動に分ける
FHAシートという造語が出てきているが、これはFact(事実),Hypothesis(仮説),Action(行動)の頭文字を取ったもので、
「空・雨・傘」の思考パターンで問題解決力を高める | PHPオンライン 衆知|PHP研究所
を参照にしている。
よくわからないと思うので、FHAシートの概念図をみながら説明していく。
内容は簡単。バックトレース、Google検索、デバッガーを用いることでエラーに関わる「事実」を左に記載し、そこから伸びるように線を引き、真ん中に「仮説」という名でエラーの原因を複数列挙。仮説を実行していき、右に「実行結果」を列挙していく。
これの長所は大きく2つ。1つは「ワーキングメモリーの削減」。もう1つは「このシートの型通りに埋めるということは、実験結果を可視化するということと同義なので、最悪この実験結果を上司に出すだけでアウトプットを出すことができる&デバッグ方法やアドバイスを頂ける」という点だ。スキルの乏しい初心者のうちは悩んでいるだけでアウトプットが出ないということが往々にしてある。FHAシートで可視化することによって、役に立ってない感という無力感を払拭できるので胸を張って業務に取り組むことができるのだ。
以上のことを踏まえながら、コードを書いていくことで技術開発を爆速で終わらせることができる。
ここまで読んでかなり辛くなってきていると思うが、次で最後だ。もう少しの辛抱。
7 ストックにする
さて、ここで質問。技術力とは一体どのようなものなのだろうか?
メソッドをたくさん覚えていること、アルゴリズムを理解していること、人によって十人十色な答えが返ってくると思う。
僕は技術力の定義を「顧客の提案に対して、再現性のある知識を駆使して問題解決していく力」と定義している。そして、その「再現性のある知識」を一言で「ストック」と定義しており、このストックを独学や実務を通して集め、分かりやすくまとめることが、技術力を高める一番いい方法であると考えている。
さて、ストックを集めると言ったはいいが、どんなものがストックになり得るのか、そしてどのようにして分かりやすくまとめて再現性を高めるのか。それをフレームワークに沿って説明していく。
7.1 Dmac分析を行う
Dmac分析とは「ハッシュ化とは?」「MVCとは?」といった言葉の定義から、外部ライブラリやメソッドの使い方までDmac図にしてまとめて、知識の再利用性を高めるためのフレームワークである。
先述の通り、(Dmac分析で)ストックを増やす=技術力がつくということなので、積極的に分析をしていきたい。
なお、Dmacはそれぞれ転用、メリット、抽象、具体例の頭文字を取ったものである。
抽象:言葉の定義と概要説明。
メリット:その名の通り。
具体例:ソースコードやリアルでどうやって使われているかを記載。
転用:自分で使うとしたらどう使うかを記載。
これに関する詳しい説明は別記事で書いていこうと考えている。取り急ぎ、どのようなものをストックするのかを記載していく。
※ストックするもの
①「言葉の定義」「フレームワーク」
②「外部ライブラリ」「メソッドの使い方」
③エンジニアが実装する時に必要なパーツ
④インターネットで顧客がしたいこと集
⑤エラーの原因パターン、アンチパターン
7.2 技術の習得(血肉化)
学習フレームワークマニュアルを回して抽象と具体を行き来することで応用が利くツールを使用法を含め、把握しているのでより多くの問題を解決できるようになる。
以上を駆使することで、再現性のある知識を短期間で量産することができるため、技術に対する理解をしながら技術開発を爆速で終わらせることができる。
8 おわりに
以上が、学習フレームワークマニュアルの全貌だ。
これによって、業務の具体的な流れや方法について逐一迷うことなく、業務の内容を再現性のある知識(=ストック)として保存することができる。
実務で悩んだ膨大な時間と10000文字の超大作を経て、霧は晴れ、大海を進むための地図とコンパスを作り上げることができたのだ。あとは地図の内容を軌道修正しつつ、前に進むだけだ。頑張っていきたい。
ご拝読ありがとうございました。やさしいマサカリなど頂けると幸いです。