開発者にとってのコードベース、ストックとフロー

## はじめに

業務アプリケーションの開発を、リーダー/リードエンジニア的なポジション（当社内用語ではアプリ/アーキポジション）で複数のチームを通してここ6,7年ほど開発しています。

このときのコードベースを開発者にとって高い品質に保ちたい育てたいという思いと、一方で重要なビジネス的スケジュールから落とし込まれた、期限的に不可能ではないが余裕があまりないという開発タスクを幾度となく消化したり、数年の月日とともに陳腐化した採用技術、実装方針、古いライブラリバージョン、低速な単体テスト、などいわゆる技術的負債がでてきました。

声掛けだけだとどうにも進まないこれらを、どうバランス取っていくかについてよく考えているので吐き出していきます。本来はFour Keysのような（観測可能な）メトリクスを取得＋チーム目標とすべきだと思いますが、そこまで至っていないです。観測すべきものが何なのか？という段階でのモヤモヤ文章です。

## フローとストック

日々の開発タスクをこなすのがフローだとします。それを通してコードベースに蓄積される知財がストック。ただし、ストックは時の試練で陳腐化の圧力を受け、常にメンテナンスを行わないと負債になりえます。メタファーなので難しいですね。マンションの修繕積立金のように、定期的にガタが来ているところを改修したり、日々管理人さんがやっているようなお掃除が必要です。

おそらく、今の開発タスクだけをこなして評価されるジュニアメンバーや、開発チームに長居することはない、アルバイト感覚のメンバー（でかつ開発タスクを行うことがミッション）だと、明示的にコードベースのブラッシュアップにかける情熱は無いので、開発規約（静的解析、コーディング規約、テスト規約、ドキュメント作成ルール）などの最低限のバーを設けてそれを突破してもらう形になるでしょう。

スキルセット的にも、マインド的にも、フローで手一杯なメンバーが増えれば増えるほど、ストックの筋肉質さが毀損されていく気がします。

## なぜコードベースを開発者にとって品質高く保ちたいのか

色々理由はありますし、開発者体験という概念もあります。個人的には、 **見積もり精度** に大きく影響するからというのを上げます。

- これくらいでできるだろう、と思ったことが例えば既存のテストが実はランダムにエラーになり、そちらの解決に時間がかかった
- これくらいでできるだろう、と思ったことが、実は既存のドキュメントが陳腐化している面がありそちらを直さないと本題に着手できない
- これくらいでできるだろう、と思ったことが、予期せぬ依存関係がありそちらを解決しないとできない

直感的にこれくらいだろう...というのが、実は新規開発と追加開発で、実装量が少なくても影響度調査、一貫性のある設計、業務影響がないようにデプロイリリース、初動監視などで見込みがズレるケースはみなさんも何度も経験しているかと思いますが、コードベースの品質が低い場合、それを見込んだ作業見積もりの難易度はさらに向上します。それらのバッファを積んで見積もりを出すが、積みすぎると不信感を持たれるケースもあり、現実的なラインを提示することは難しいです。

特にコードベースに慣れていない場合、理想的なコードベースであると仮定して見積もりを立てがちです。3,4割バッファを入れたところで吸収できなくなってくると危険です。

## 地雷を残さない

さらに経験談ですが、ジュニアクラスが夕方17時、18時以降に開発タスクに集中して取り組んでいる時に、既存不備にハマって数時間を溶かしている場面をよく見ます。日中帯であればだれかがヘルプできますが、夕方以降は人が抜けていくのでフォローが甘くなり、くらいやすくなる形です。ちょっとしたハマりでもだれかがフォローするので、優先度を下げても大丈夫、は上手く機能しない場合があります。

人がどこでハマるのかというと、全てでハマる可能性があります。ハインリッヒの法則とか、「ヒヤリ・ハット」と同じ用に、少しでもアレ？って思ったら、改善していかないと後々のメンバーが時間を溶かす可能性があります。事故（ハマり）が発生しうる状況だと、必ず後々ハマる人がでてくる、という認識が必要で、そのためにガードレールやらCIなどの開発フローの整備が必要です。


## 作業見積もりにバッファを入れすぎると

現行システム、コードベースの構成が理解できないと、対策として大きめのバッファーを積むというのがあります。ある意味、その大きめなバッファーすら食いつぶすのが常なので、実は大きくないことが多いです。

しかし、その場合は依頼者側から見ての費用対効果が悪くなり、その機能改修そのものがオシャカになる、あるいは優先度が下げられるということも多々発生します。この程度の改修でなぜこんなに時間がかかるんだろう？というのは非開発者でも直感的に思うことですし、自分たちでも客観的に見ると同意する面もあるでしょう。

正確に見積もりができないという状況は、ビジネス上の打つ手を制限してしまうことにも繋がり、開発者体験の言葉で済まして、看過して良いことではないです。

## コードベースを高品質に保ち、オンボーディングコストを下げる

オンボーディングの負荷を減らしたいというのは、拡大するチームにとって重要です。メンバーの負荷が上がって来た時にメンバー追加は有力な選択肢ですが、オンボーディングコストが高い場合、逆に既存メンバーの負荷が上がってしまうため、メンバーとしてもメンバー増員に難色を示すケースがあり、稼働が高止まりしてしまうことすらありえます。

そのためにも、教育コストはなるべく下げ、質問があれば回答はドキュメントのURLと簡単な補足を返すだけで解決できる方が良いです。なるべく早く戦力化したほうが、新規参画者の満足度も高まり、より高い次元の活躍も期待できます。

システム構成だけではなく、ドキュメント、アーキテクチャ方針なども含めて新規参画者にも分かりやすく技術スタック、構成管理を取っていく必要があります。


## 開発者にとってコードベースのストック的価値とは

よくできたテスト。高速に動かす。一貫性のある開発者体験、ドキュメント、etc.

テストの信頼性はとても大事です。既存のテストが壊れなければ、そうそうおかしなデグレはしないという状況を作れると、開発者も安心できますし、新規参画者からはなおさらでしょう。

ベースラインが安定すれば、より発展的な議論もできます。発展的な議論ができれば、チームも雰囲気も明るくなり、チャレンジが増えればメンバーの所属意識、満足度も高くなります。開発者体験が指す言葉に近くなっってきました。


## コードベースのストック的価値を上げるためには

マンションの修繕積立金という話をしましたが、まずは目先の小さな改善を繰り返すことから始めるべきだと思います。週に1日とか、定期的にリファクタリング向けのスプリントを取るチームもあると聞きますが、さらにスモールスタートすると良いかなと思います。

その時ですが、システム全体の開発フロー、ドキュメントなど下回りの改善は特にリードエンジニア的な存在が率先してやるべきだと感じました。まずはリーダー層から背中を見せる必要があります。また、この手の機能横断的な仕事は設計の塩梅が難しく、リーダーから見るとそこそこでも、メンバーから見ると難易度が高いもので、PRレビュー時に手戻りが発生しやすいタスクです。

リファクタリングは期限が比較的緩いし、難易度が低いとしてジュニアクラスのアサインをする場面がありますが、あまり有効に働くことはないです。最初の1,2タスクは簡易なリファクタリングタスクをアサインするのはありですが、ジュニアをジュニアとして扱いすぎると、本人もそのように振る舞ってしまいます。背中を預ける同僚として早く扱い、ビジネスにコードで直接貢献できるようなタスクを早めにアサインするべきだと思います。


## 天引きで時間枠を確保する方法

例えば、1on1をする時間は、1日の作業時間から天引きのようなものとして捉えて実施しているチームが多いのではないでしょうか。1on1が無いチーム運営、今となっては想像できませんね。

同様に1日1時間、改善作業を行うことは不可能ではないと思います。しかしジュニアレベルだと厳しい面も多いです。日々のタスクで手一杯ですし、コンテキストスイッチもそこまで上手でないので、オーバーヘッドも大きいです。

天引きで時間枠を確保し、改善活動するのは準リーダー級以上で行う、というのがいいかなと思います。


## おわりに

コードベースの改善に、専任メンバーを当てたり、20%ルールにしようといった話は私の周囲ではよく出るのですが、専任メンバーのキャリアまで考えるとうーんとなったり、20%ルールは言うは易しの典型で、実際には厳しいスケジュールのプレッシャーで数回程度であれば実現性はあれど、継続性はかなり厳しいと思っています。

スケジュールのプレッシャーについては、まずそれなりの見積もり精度を身に着けなければ、後手後手に周るかビジネスカウンターとの信頼性が下がるかどちらかに落ちがちです。

見積もり精度を上げるためには、認識齟齬が無いようにコードベースを理想的な状態に近づけるのが前提です。特にジュニアメンバー、新規参画者が多い場合は、余計なハマりどころで数時間が溶けるのはザラなので、体制によってはかなり力を入れたいところです。

チームの体制、規模、習熟度など様々なパラメータによって、どれくらいストック的な部分に投資すべきか、どのような運用にすべきかは、来年以降に見極めていきます。みなさまも良いやり方があれば教えてください。