コーディングとの向き合い方 Before - After

# はじめに
今年もアドベントカレンダーの季節がやってまいりました。
毎年スプレッドシートに関する知見の共有を記事にしてきましたが今年は趣向を変えて、これからエンジニアリングを学ぶ方や学びはじめたけどどのように学習を進めていけば良いか悩んでいる方に向けて、私自身の経験から自身がどのようにコーディングと向き合っているかをBefore - Afterの形式でお伝えできればと思います。

過去に掲載した記事については下記のリンクをご参照ください。

* [Google Apps Scriptを使ってみよう(前編)](https://qiita.com/omomukumamani_piroshi/items/beeb51d8c28369167cd9)
* [Google Apps Scriptを使ってみよう(後編)](https://qiita.com/omomukumamani_piroshi/items/585c4478474b8d8c571c)
* [Google Apps Scriptを使ってみよう(おまけ編)](https://qiita.com/omomukumamani_piroshi/items/03425833a0bdfc1249ca)
* [カスタム関数でキャラクタースキルの詳細をチェックする](https://qiita.com/omomukumamani_piroshi/items/1ce62b2178af4aead494)
* [Google スプレッドシートを使って文章を検証しよう](https://qiita.com/omomukumamani_piroshi/items/e749fe5a2b64e9ff9908)

# 自己紹介
2014年12月よりQAエンジニアとして、業務効率化や障害削減に関係するツール類の作成を主として業務を行なっています。最近はCEDEC2022で翻訳QAに関しての取り組みについて発表致しました。

# 今回紹介する内容
タイトルに記載した通り、今回は私自身がこれまでの経験を通じてコーディングとの向き合い方がどのように変化したか、Before - Afterの形式でお伝えします。
「こうするのが良い」という話ではなくあくまで私自身がそれまでどのようにしていたかと、どのようにすることが良いと思い変化したかについてのお話となります。
全ての方にとって良い選択であるとは限らないのでその点を踏まえて読み進めて頂けたらと思います。

# コーディングについて
### Before：
「動くものを早く作らなくちゃ！とりあえず同じことやってるコードないかな〜。とりあえず丸パクリで関数名と変数名書き換えれば良いか」

宿題でよくやってしまうパターンです。
動作するところまで作るという姿勢は評価するとして、応用が必要な追加の課題を出されたときにもコードを探してネットをさまようことになります。
他人のコードは参考程度に、内容を理解するようにしましょう。
### After：
「要件の分析、成果物の設計、仕様の作成、実装、テストを行う」
どれかに抜け漏れがあっても想定外の時間的・物理的なコストがかかります。
エンジニアリング初心者の方からよく聞く、「どこまで作れば良いかわからない」はこのプロセスが抜けているため発生します。

* 要件の分析(求められているものを洗い出す)
* 成果物の設計(何を作るのか)
* 仕様の作成(どのように作るのか)
* **実装(ここではじめてコーディング)**
* テスト(仕様どおりに動作することの確認)

事前に要件・設計・仕様をはっきりとさせておく事でゴールが明確になります。
またしっかりとテストが書かれていることが前提になりますが、機能の追加を行う時にもテストを行う事で既存機能へ影響がないかを確認することもできます。
仮に影響があったとしてもその分テストを追加していくことで将来的に検知が可能となります。
結果としてBeforeと比較して時間的・物理的なコストを抑えることができます。

## デバッグについて
### Before：
「デバッグ？知ってる！動いてることの確認でしょ！大丈夫、エラー出てるけど動いてるから」

動いているとはなんでしょうか？エラーが出ているけど動いているというのが何とも言えない怖さがありますね。
まずエラーが出ていたら動いているから大丈夫だとしても修正しましょう。
デバッグの第一歩です。
### After：
仕様の作成とテストが役に立ちます。
仕様の作成ではどのように作るのか（そして振る舞うのか）を定義します。
そして定義した振る舞いの通りに動いているかを確認するためのテストを実装します。
実装された全てのテストをパスすることではじめて「動いている」と言えます。
**「正常な動作」** とは何かを **テストコードにより明確にして**、全てのテストコードで合格になるように**バグを修正していくプロセス**がデバッグです。

## ログについて
### Before：
「ログ見ろ？ログって何？英語？難しくてわかんないし、動くようになれば良いよね」
いわゆるエラーをはじめとするツールやコンパイラが出力するメッセージですが、プログラミングの初心者の方ほど見ない人が多いと思います。私が新卒のとき会社のある先輩はワーニングのログを完全に無視していました。今思うとワーニングのレベルが厳密だったのかもしれませんが、その場合には必要な情報が他のログに埋もれてしまうためコンパイラに指定するワーニングレベルを下げるべきです。
必要な情報でなければユーザーに通知することはありません。
### After：
エラーログを例に説明します。
* エラーログの**確認方法**は？(ウィンドウ、ファイル等)
* エラーが発生した**ファイルと行番号**は？(スタックトレースでわかる)
* エラーの**内容**は？(とりあえず読む。読めなかったら調べる、**公式ドキュメント以外は過信しない**)
* 必要に応じてデバッガを使う(変数の内容が確認できる。想像で終わらせない)
* テストコードを書いて**同じエラーを発生させる**(仮説の検証と修正の確認ができるように)
* 書いたテストコードはまとめて実行できるように(リグレッションテストに使う)

ログはソースを書いた本人が想定していない**問題を解決する手がかり**となります。
是非ログを読むところからはじめてみてください。

## 機能の追加や仕様の変更について
### Before：
私「よし〜、作り終わったあとは動作を確認してもらって…」
A「作って貰った機能だけど、ここがうまく動いてなくて」
私「あ〜、それ仕様決める時に何も言われなかったので作らなかった」
A「そしたら、この機能にこれができるように機能を追加して欲しいんだよね」
私「えー、今言われてもコピペで作ったからたくさん修正するところあるじゃん…」
A「じゃ、あとよろしくお願いします」
私「ま、一括置換して、足りない機能コピペすればいいか」

20年ほど前のゲーム開発の現場での会話をほぼそのまま書きました。
やっぱり黙ってて良いことは無いですね。やることが増えたとして、後々やるのであればそれが本来のやるべき事ですし。
加えてこの会話で危険なのは修正箇所がたくさん存在することと、その修正方法が一括置換と機能のコピペです。
機能の追加や仕様の変更を依頼された時のことを考えてという事ではありませんが、普段から極力作らなくてはいけないものかを考えることと、可能であれば減らすことを考えると良かったかと思います。
### After：
* 要件の追加・変更(データレベルで対応、できなければ追加・変更のための要件定義)
* 要件定義(成果物に求められるものを明確にする)
* 要件定義のレビュー(関連する人たちと認識を合わせる)
* 設計(重複する機能を作らない)
* 設計のレビュー(必要であれば。相手がいないとできない)
* 仕様(要件を満たしているか)
* 仕様のレビュー(必要であれば。相手がいないとできない)
* 実装(ものを増やさない、できればリファクタリングで減らす)
* テスト(追加した実装へのテストコード)
* コードレビュー(必要であれば。相手がいないとできない)

いかがでしょうか。機能の追加や仕様変更は規模は異なりますが**最初のステップからやり直し**になることを考えると、**手を動かさずに済むうちに解決**した方が結果としてみんなが楽になるような気がしませんか？
お願いされたことを早く終わらせるというのも大事だと思いますが、コーディングにおいては**新たに作る必要があるかを検討**して**いらないものは作らない**、これが意外と重要であることを実感します。

## まとめ
つらつらと書きましたが、最近は色々と他の人の成果物をレビューすることが多かったので、自分自身を振り返りながら書いてみました。全ての人に役に立つ内容だとは思いませんが、同じことを思っていたりこれからコーディングを学ぼうとしている方が何かのタイミングでこの記事を思い出し参考にしていただけることがあれば幸いです。