1人で50,000行(最近見返したらこれくらい書いていた)のリニューアルをした時に行ったこと

# はじめに
先月に約~~35,000~~ 50000行(コードdiff)のプロジェクトをリリースしました。
従来からある管理画面のリニューアル案件です。

工数にして約2.5人月(全体で多分4人月くらい)を2ヶ月でメインコーディング1人(+協力会社さんのhtmlコーダーさん工数1人月くらい)で完遂。
一人で行った短期間の改修では今までで最大規模でしたので書いて残しておこうと思います。

先にキャッチで書いた「1人で」というのは半分あってますが、半分間違っていて、実際はhtmlは外部に書いていただいております笑
が、html以外でもコードdiffにして1人で~~10,000~~ 20,000行くらいは書いたと思いますので。。。

一説には一人にプログラマが把握できるコード量は10,000行と聞いたことがありますので、自分がなぜやり遂げられたのか、
コツや特に意識したこと、もっとこうすれば良かった！　などを記載しておきます。

同じスタートアップ界隈では一人で同じような案件をやる人が多いと思いますので、誰かしらの参考になれば幸いです。

# プロジェクト概要
* プロダクトのコンテンツ管理画面リニューアル
* 期間：約3ヶ月
* 工数：実装〜リリースがおそらく2.5人月くらい
* フレームワーク：ネイティブのjavascript(フロントエンド)、CakePHP3(サーバーサイド)
* ざっくり機能：
  * フロントエンド：遷移は一覧画面内のモーダルでcreate, edit、delete。一部だけ一覧→詳細(create,edit,delete)。
  * サーバーサイド：アカウント毎のロールベースアクセス認証・認可有り。リソースのCRUDが4つほど。その他AWSのサービスとの繋ぎ部分や、cron実行のバッチが5, 6本
  * テストコードはなし。今回も書かない

プロダクトの内容や管理画面の詳細は、今回の主旨と離れてしまうので割愛。

# 35,000行コード対策
## 全てのコードを「把握する」を捨て、「思い出すまでの時間を短くする」「みればすぐにわかる」コードにする
大まかには下記を行った。詳細は次の段落で解説。
はじめ時間がかかるがプロジェクトが進むにつれてストレスが少なくなる。


１、設計、クラス、メソッド、ロジック、変数をとことん単純化することに注力する

２、コメントにはそのコードに至った背景を記載する

３、コミットを最小化する


# 全体の流れと各所管
## １、UI部分の決定
目的：より良いUIの決定
参加者：デザインの協力会社さん、CEO、CTO、出れる技術部の人たち＋自分

UIの議論は上がってきたデザインに対して大人数で気になるところや改善点を発言していく感じの打ち合わせ。
実際に改修作業を行う立場として自分も参加。
3~4回の打ち合わせを経て、最終的にはデザインをxdファイルで納品していただきました。

### 意識した点、実施したこと
* より良いUIを議論する中でもぼんやりとフロントのギミックの作りやサーバサイドの仕様を自分の中で持ちながら参加。
 
* 機能要件を把握できるように準備。自分は暗記が苦手なので、表やメモを用意して記憶できない点は記載を行った。
 
* UIのFIXが近づく段階で変更点を可視化。改修点一覧のようなものを用意し見積もりを記載。

### 良かったこと、改善点
* 把握しきれない要件・仕様はメモでカバー

* UIのFIXを待たずに改修点一覧を用意しておくことで、早くから自分以外にも改修点と工数の大小を示すことができた。これによって、リリース時期の見積もりや交渉がすんなりできた。

* 改修点一覧があることでピンチの時にタスクの切り出しがしやすい（今回は特にピンチになることもなく自分でやってしまいましたが）

ここら辺はSIでPMやPL、リーダをやっていたので、そこで実施していたことを実施しただけで、特に新しい取り組みはしていないつもり。
PMやPLの目線から見ると、規模的には簡単に一人で管理できる規模。

## ２、外部のパートナーさんにタスクとデザインの共有、すり合わせ
目的：htmlを作成していただくにあたってデザインの共有と想定している仕様、期間などの要件を伝え、すり合わせる
参加者：html制作会社さん、自分

デザイン会社さんからxdファイルを受け取る前に、事前に把握している仕様とデザインなどを見ながら共有。
「画面を作成していただく」という抽象的な言葉の認識を合わせる打ち合わせを設けた。

### 意識した点、実施したこと
* そのデザインになった意図をなるべく多く伝え、納得して作成していただけるような伝え方をしたつもり

* ギミックに関わるjavascriptは担当していただいたが、実際にそれがどこにあたるのかを、具体的に一つづつすり合わせ。

* cssやjavascriptの実装方法はできる部分は口頭でも良いので決めておく

### 良かったこと、改善点
* 作成してもらう部分を具体的にデザインを見ながら一つづつ行ったことで認識の齟齬をなくすことができた。

* cssはできる限り共通化してもらう必要があった。実装段階で機能ごとにcssファイルに切り出したり、共通化したため余分に工数がかかってしまった。

* その他実装方法については大きく認識に乖離はなくうまくすり合わせられたと思っている。

cssの共通化については反省点で、後にhtmlとサーバサイドをくっつける段階で自分で共通化して切り出すことになってしまった。
しかも共通化したために、その後に変更があった場合、協力会社さんからもらうcssのdiffを特定して充てるということになってしまった。

## ３、自分のタスクの整理
いよいよ自分のタスクへ。改修点一覧を見ながらタスク順を整理。
クリティカルパスを把握くして納期を短縮すべく組み立てを行う。

### 意識した点、実施したこと
* 改修点一覧をBacklogのチケットへ転機

* 工数も見るが、コーディングでどれが先にできていれば他の実装が捗るかを検討

* htmlが開発会社さんから上がってくる前にできる部分はやっておき、htmlが来たら繋げるだけにしておく

* htmlが上がってくる前に集中して組み上げてしまう計画を立てる(半力技w)

* 少々無理してでも前倒した計画を立てる(半力技w)

### 良かったこと、改善点
* Backlogタスクをcloseしていくことがある種の達成感になってモチベーション維持に繋がった

* ここでの順位付がうまくいって、htmlと繋げる段階の工数を削減できた。その後サクサク画面が出来上がって気持ちよかった。

* リリース前にインフルエンザにかかりまさかの一週間休暇ww　前倒しした計画を立てていたことが幸いした。

## ４、実装〜テスト
Backlogチケットごとに実装へ突入。設計書は書かない。
他の作業を行ったり、UIをFIXさせたるするために、ここまででおよそ一ヶ月経過。残り実装と単体、結合テストで約2ヶ月を要した。
ここがメインで残しておきたいところなので少し細かく書いておく。

### 意識した点、実施したこと
#### 命名規則、実装規則
* 自分の中で決めて、メソッドや変数は見ただけで何をしているかわかる命名をした
* get、setなどはセッター、ゲッター以外にはなるべく用いずsqlを実行するならばfetch、データ編集ならばeditやconvertなどを用いる
* フラグを返却するものはis、可能性を返却するものはcanなど
* 複雑になりがちなifの条件は否定形ではなく、なるべく肯定系で書く
* 早めにreturnできる場合はreturnすることで階層を浅くする

#### 基底クラス
* コントローラー基底クラス、バッチ基底クラス、サービス基底クラスなどのベースクラスをそれぞれ作成し、開始処理や終了処理は何回も書かないようにする
* initializeやログ出力など記載が多くなるおきまりの部分はメソッド化して一行で済むようにする

#### メソッド
* メソッドを再利用できるように汎用的な作りにする。fetchしたデータを渡せばプルダウンを生成してくれるメソッドやs3へアップロードするメソッドは共通化しておく。
* 実行するタスクは一つに切り出す
* メソッドの用途と違いがわかるようにDocはしっかり書く

#### コメント
* コードやロジックを実装した背景はすぐに忘れてしまうので、王道から外れた仕様の部分は、そこに至った背景を必ず記載した
* コメントは書いたときと、コミットする前の2回確認して、少しでも抽象的だったり理解できない部分は書き直す

#### コミット
* なるべく修正一つの最小単位でコミットする。戻しが発生した時にソースを書き直すより、コミットを探して戻した方が楽で信用のあるコード。テストの手間も省ける。
* すぐにコミットの内容がわかるように修正は背景も含め簡潔に書く
* コミットにどのチケットの修正なのか、チケットの番号など対応する番号をインデックスとして記載する
* コミット時にセルフコードレビューを必ず行う

#### 単体・結合テスト
* 単体テストは仕様書を作成していたらキリがないので省略w　実装しながら動かしてできる限りバグを取り除く。
* 結合テストは仕様書を作成。単体レベルのバグも考慮して一部単体テストも混ぜるような観点で実施。

### 良かったこと、改善点
* この辺りはリーダブルコードの内容をそのまま実践した感じ。細かくて些細なことでも意識して記載することで、後でコードを見返したときのわかりやすさが雲泥の差だった

* メソッドで実行するタスクを一つに絞ることでデバッグで目処がつきやすくなる

* ロールベースアクセスの認証・認可はhtmlと繋ぐ段階で仕様に対応する設計になっていないことが判明し、差し込みで設計を改修した。今回のリニューアルの肝となる大きな改修点だったので痛手になった。設計の未熟さからくるものだと思っているが、反省を活かしてより良い設計にブラシュアップしていこうと思う。

一人プロジェクトは、自分のコードだからわかるだろと思って手抜きになる傾向があるが、書くステップが多くなるほど手抜きするとロスタイムにつながる。
ここらへんはしっかり実践しておいたことで助かった部分が非常に大きい。 

実際に後期が厳しい作業ではタスクを絞って実施することが肝心になることが身にしみた。
今回は単体テストが犠牲になったのだが、命名規則やクラスやメソッドを工夫することでテスト→改修のイテレーションにかかる時間が短くなり、その結果テスト工数はかなり削減できると感じた。


#　まとめ
* 複数人が関わるプロジェクトになっても今回行ったポイントは使えるのではないか。特に実装の部分は意識したい。

* 今回のようなやり方は、SIなどの工程毎の成果物を求められるプロジェクトになると工数の削減はなかなか厳しいかもしれない。あくまでも自社プロダクトのweb開発なのかと思う。

* 納期が短いプロジェクトのリスクは、仕様変更に対して柔軟でないこと、仕様を忘れて書いた部分を読み直す作業に時間がかかることなど複数あるが、一人の時でもあらかじめリスクに対応した工夫をいくつか用意しておくと安心(インフルはリスクに入れていなかったので反省w)

* 実際にコードレビューなどは行えない数のコードを書いた。コミット時にセルフレビューを行うことでかなりバグは取り除けることがわかった。

結果、一人でも複数人でもプロジェクトの大小に関わらず必要なことは同じであるということ！笑

ありがとうございました！以上です。