開発生産性の維持のためのルールを考えてみた

この記事は「エンジニア組織の開発生産性・開発者体験向上の取り組みをシェアしよう！ by Findy Advent Calendar 2023」の20日目の記事になります。

https://qiita.com/advent-calendar/2023/developer-productivity




これは自分の経験を元に、こんなことをやると開発生産性を維持できるのではないか？ということで、システムを作り始めるときの最低基準として適応を検討すると良いのではという項目を作ってみました。
まだ開発組織には適応できていないけども、機会があったら適応してみた。



# なぜ維持なのか？

開発生産性を維持を意識する必要がある理由で、今回ターゲットにするものはこの3つにしました

- システムはリリースしたら終わりではなく、開発し続ける環境が重要
- 技術的負債は発生のスピードの違いはあるが、ゼロにはならない
- 開発生産性は自動的に高まるものではなく、放っておくと劣化する


### システムはリリースしたら終わりではなく、開発し続ける環境が重要

リリースしたら終わりというシステムの開発の方法が当たり前でしたが、市場の変化のスピードが上がるに連れて、新しい機能を追加し続けることが重要になってきました。
まさにアジャイルな開発が必要になっている場面が増えています。

逆を言うと、プロジェクト型のシステム納品で仕事が終わる場合には、技術的負債に注目することに価値を見出すことは難しいかもしれません。

### 技術的負債は発生のスピードの違いはあるが、ゼロにはならない

上手く設計したり実装することで技術的負債をなるべく抑えるように作ることは出来るが、事業や環境の変化、変更の積み重なりによって、どんなに良いシステムでもいずれは負債は発生します。

できるだけ発生を抑える手法は多く生まれています。


### 開発生産性は自動的に高まるものではなく、放っておくと劣化する

システムがまだ何もないときには何の制約がないが、システムを作ると既存のシステムの運用が必要になります。

ルールや進め方があり、メンバーが増えるとコミュニケーションの方法が定義されます。

システムは基本的に拡大しかしない中で複雑性が増し、認知負荷は増えます。
リリースをすれば運用で想定外の障害などの問題も起きます。

リリース後のシステムは、システムを動かし続けるということにリソースを取られ、システムを純粋に開発する時間を取ることが難しくなっていく。つまり、何の手も打たなければ開発生産性は下がる一方だと考えます。


しかし、逆を言えば何かしらの手を打てば開発生産性を少人数で小さなシステムを開発しているときと同等の状態を維持できるのかもしれません。アジャイル開発やプロセスの定義など開発パターンが今も生み出されています。


# 維持という視点は中長期の戦略が必要になる

短期の目線では絶対に解消できません。なぜならば、負担の効果は１つ１つはわずかで、積み重なって大きな重さになっていたり、解消したとしても目に見えない問題が解消しただけで、何かしらに劇的な変化を起こすものではないからです。

まさに技術的負債と呼ばれるものも同じように積み重なって重さとなります。


それを解消するにも、小さな取り組みの積み重ねの必要があります。


# この記事でやりたいこと

生産性を下げる原因である技術的負債が絶対に生まれるならば、大事な観点としては、技術的負債を産まないことや抑えることではなく、技術的負債に対処するときに、技術的負債を対処しやすい環境を作ることではないか？

そこで、「技術的負債を対処しやすい環境」の最低基準を作り、開発を行う開発チームの全ての基準にできないだろうか？と考えたことです。

# 今ある仕組みではダメなのか？


スクラムでは抽象的すぎて、fourkeysは抽象かつ立ち上げ時点からやるには仕組みが大規模過ぎます。
もっと具体的でかつ明確な数値がわかる指標を作りたいと考えています。

また、具体的な定義をすることで次の項で触れるような効果も期待してます。


# 基準にすることで期待すること

技術的負債の拡大を防いだり、適切なタイミングで対処したいと考えています。
また、技術的負債に対処するときに必要な状態が維持するような項目を定義したいです。

基準があることで、以下のような期待をしています。
- ビジネスメンバーが理解できる指標を作る
- 議論の当たり前が逆転する
- 技術的な根拠の把握する負担の短縮


### ビジネスメンバーが理解できる指標を作る

ビジネスメンバーはシステムの状況がわかりません。
エンジニアも危険な匂いを感じたり、感覚的なものを言語化することが難しいことにもどかしく感じています。
その状況の結果として障害が多数発生するような状況になってから、急いて対応したりすることになります。

そのような状況になる前に防ぎたいですね。

### 議論の当たり前が逆転する

エンジニアの中では明らかに合意しているシステム的な対応があっても、ビジネスメンバーに説明しきれずに作業が進められられないことがあると思います。
しかし、システム開発の常識として最低限の基準があれば、説明不要で開発に必要なことで、みんながやっていて、最低限必要なことですと説明するだけで済むようにしたいです。

絶対に必要な常識となっていればエンジニア説明責任を逆転して、逆に最低限のことを犠牲にする理由の説明をビジネスチームに求めることが出来るようにしたいです。


### 技術的な根拠の把握する負担の短縮

技術的負債の対処で難しいのは、現状がどのような状況になっているかの調査などに多大な時間がかかります。
調査は実装の変更に手を付ける前に必要になってしまうため、意思決定の判断すら難しいというジレンマに陥っている間に、技術的な負債が膨らんでしまったり、生産性が低いままで長い間開発を続けなければならなくなってしまいます。

そこで、調査などの時間は最低限の時間で判断までを最速で出来る環境を作りたいと考えました。


# 具体的な最低基準としてやるべきことは？

まずはこの５つに絞り込みました
- 意思決定を記録する (ADRを行う)
- ユニットテストの自動テストカバレッジ50%以上
- 開発と運用と差し込みに使っている時間を計測する
- インシデント数、アラート数、エラー数を計測する
- 開発工数の2割を開発の質を高める時間に使う




### 次点
- 改善タスクを１つ以上常に実行している
- 正常系のE2Eテストで全てのAPIが１回以上実行される
- 開発する人の数 ÷ 2 以上の開発ストーリーを同時に進めない
- 失敗の可能性があるチャレンジ(チームの変化のタスク)を１つ以上する
- 開発未来MTGを月１回行う

これらはトレードオフされやすいので、もう少し深く検討してみたいと思いました。
ただ、このまま適応しても、チームのプロセス改善には繋がると考えています。

それぞれ、少しだけ概要のイメージを説明していきたいと思います。



### 1. 意思決定を記録する (ADRを行う)
アーキテクチャディシジョンレコード (Architectural Decision Records)です。
これは、どのような意図でその技術が採用されたのかを記録として残すものです。
意思決定の議論中にも役に立ちますし、あとからそのアーキテクチャを変更するときにも把握しやすさの向上やリスクの低減に繋がります。

システムが稼働してしばらく後に、アーキテクチャ検討のときに意図を持って今の構成になっているのか、制約や何らかの理由があってそのアーキテクチャの構成になっているのか、検討そのものが無いままに作られたのかが分かるだけで意思決定をしやすくなり、技術的負債の対処にかかる時間を減らすことを期待します。

最近は事例も増えてきたので、導入の意思決定がしやすくなっているのでは無いでしょうか

https://user-first.ikyu.co.jp/entry/2023/12/13/115112

https://qiita.com/hanhan1978/items/067abd7b28b0807e8c87

https://tech.route06.co.jp/entry/2023/07/04/130958


### 2. ユニットテストの自動テストカバレッジ50%以上

ユニットテストは開発中であっても、開発生産性の向上に繋がります。
カバレッジを高めるかどうかは開発の状況によりますが、正常系テストすら１つもない状況は、明らかに開発力の低下を即座に招きます。

全力で走っていても重りをつけて走っているようなものです。
まずは、重りが軽くなるような取り組みをするべき数値として、最低限の数値は50%としました。
この数値には議論の余地があると感じていますが、最初に目指す数値としては悪くないのではないと思っています。

カバレッジの数値は低くても良いと思っています。最低限１つ以上の正常系のテストと１つ以上の以上系のテストが維持されていることが最低限で維持できると、改善がし易い最低限の土壌を維持できるのではと考えています。

内部の質を検証しやすくために最低限の質を担保して開発スピードを維持します。


https://speakerdeck.com/twada/quality-and-speed-aws-dev-day-2023-tokyo-edition



### 3. 開発と運用と差し込みに使っている時間を計測する

リリースしたシステムを抱えるチームでは思った以上に開発に集中できない環境が生まれていることがあります。
できればリリース前から計測して、運用中の問い合わせ対応や障害などの差し込み対応などでどのくらいの時間を消費していて、純粋な開発にどのくらいの時間を使っているかを計測するべきです。

この時間は細かな時間でなくても１時間単位程度の大雑把な時間やストーリーポイントで表した相対値でも構わないと考えています。
相対的に開発できている時間が、運用や差し込みに対して比較できること。
開発する時間がどのような推移を示しているかを確認できること。
が大切だと考えています。

この数値が正しく計測されていればメンバー追加のときに開発時間が現象し、受け入れのための工数増加なども見える可能性もあります。
その後、新メンバーが立ち上がってくると時間差で開発スピードが高まります。

そのような、アウトプットでしか見えない指標ではない部分での課題を見える化します。


見えにくい差し込みとの戦いは昔ながらの課題だと思います。
最初はスプレッドシードで管理するところから小さく始めるのがいいと思いますが、慣れてきたらバーンアップチャートなどを活用したいですね。

https://blog.studysapuri.jp/entry/2021/02/08/080000



### 4. インシデント数、アラート数、エラー数を計測する

エラーバジェットという考え方がありますが、考え方はシンプルで分かりやすいですが、その活用方法は組織のよってバラバラで、実は導入は難しいです。

それよりも、シンプルに数を数えましょう。
そもそもエラーとは何でしょうか？インシデントは？アラートは？

#### まず、インシデントは障害と呼ばれるものです。
これは即座に対応するべき問題であるとチームが認識したシステムの問題です。
どんな開発よりも最優先で対応されます。
このインシデントの多くはいくつかのアラートの通知から、フィルターを掛けて、即座に対応すべき問題であると認定したものになります。

#### 次に、アラートです。
多くのエラーはシステムでハンドリングされていますが、想定外の問題が発生したときには通知が飛ぶように作られていることがほとんどです。この、想定外の動きをした場合の通知の数を計測します。これは必ずしもインシデントになるわけではありません。


#### 最後にエラーです。
システムが上手く動かなかったケースを通知します。エラーには２種類あり、業務エラーとシステムエラーです。業務エラーは入力した値が間違っていたなどの人間にお知らせするエラーです。システムエラーはシステム的な不具合によって正しく動かなかったときに起きるものです。
通常、エラーバジェットで指しているエラーはこのシステムエラーかと思います。しかし、システムエラーの中にも想定の範囲内のエラーと想定の範囲外のエラーがあります。想定の範囲内のものはシステムによってハンドリングされることもあります。
ここは、本来明確に分けて対処できたほうが柔軟性と堅牢性が高まると思います。


#### インシデント、アラート、エラーがなぜ重要なのか？

ビジネスメンバーに問題にされるのは、このインシデントが発生したときのみです。
インシデントの数が多くなってきたときに、本格的に技術的負債の対策に乗り出そうと考えます。

でも、本来はそれでは遅いと感じています。


インシデントの発生はアイスバーグの氷山モデルの海上に出ている氷山の一部です。
その結果に繋がる前に大量のアラートやエラーが発生している可能性があります。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17213/a1ed0a34-e876-38a7-6710-8bd4e73f19b1.png)


その多くのアラートの数やエラーの数を追跡して置くべきです。
アラートやエラーの出ている数を集計してください。
インシデントには繋がっていないが、エラーの出ている数が増えてきているなどの現象が見えるでしょう。

大きなシステムを扱うチームでは１日に何件ものエラーが発生していることがあります。
このエラーを握り潰したり、放置することなく、推移を見えるようにしておくことが大事です。

エラーバジェットは負荷が低いシステムやエラーがクリティカルなシステムでは、クリティカルなエラーが出るまで見えなくなってしまう課題があります。

エラーの数字は１日数件かもしれないですが、月間100件に達するときには対処を考えても良いかもしれません。1日の件数とすれば小さいですが、毎月100件のノイズがエンジニアの邪魔をしているコストも無駄ですし、そのエラーは多くの場合、インシデントの種である可能性があります。

DevOpsのサービスレベルマネジメントをもう少しシンプルに見つつ、解像度を高めて見える化が出来ると良いのではと考えてみました。

https://newrelic.com/jp/blog/best-practices/alerts-service-levels-error-budgets


「エラー バジェットの使用は両刃の剣」とあるように、場面によってエラーに対する解釈の難しい設計やハンドリングが求められます。

https://cloud.google.com/blog/ja/products/management-tools/sre-error-budgets-and-maintenance-windows


PagerDutyさんのページでは通知に対して、インシデントとして動員されるまでのノイズ除去のトリアージで80-99%があると書かれています。このトリアージ手前の数字自体がそもそもアイスバーグの氷山モデルの水面下にある、数字になっている可能性があります。もしかしたらPagerDutyを導入してダッシュボードを見るだけでも出来るのかもしれないですね。

https://qiita.com/ymotomu/items/1a40022feabae53e85c9


### 5. 開発工数の2割を開発の質を高める時間に使う

開発工数の２割ということは、１週間の5営業日のうち１日は改善の日として集中できる日に割り当てても良いということです。

エンジニアであれば匂いでわかる課題をタスクを調査し、説明するコストは非常に辛いものがあります。そして、説明できないからと言って放置して良いものではありません。
調査と説明に時間を掛けるくらいであれば、無条件でやってしまう時間を作るのが良いでしょう。

これは非常に感覚的なものですが、中長期的な施策をする上ではちょうどよい比率だと考えています。開発スピードを上げる仕組みを作るための時間としてはいくらあっても足りないのですが、２割くらいが短期の成果と中長期への複利での効果のバランスが良いと感じます。

技術的負債のようなマイナス面を解消する時間としては投資しすぎのように感じる人もいるかもしれませんが、この時間にはCI/CDなどの自動化による仕組み化、開発プロセスなどの見直しによるフローの効率化、最新技術の知識のキャッチアップによる技術の底上げ、など、負債のようなマイナスをゼロにする維持作業だけでなく、今のチームのより良い力を引き出せる仕組みを磨くことでプラスの力を伸ばすことが出来ます。

この複利の効果によって、マイナスに働くことを止めずに見ているか、プラスに働かせる仕組みを作っていくか、どちらを選ぶかによってチームの生産性は中長期的には大きく変わるでしょう。

この2割という割合はあくまで目安で、状況によって5割までは柔軟に変えれると良いでしょう。
それ以上の割合にするときには、大きな技術的負債や開発効率のテーマがある場合になると考えています。

ゆとりがなくなると、中長期的な改善の時間を捻出することが出来ず、永遠に開発効率が悪いままです。プロジェクト的に一括返済をする方法もありますが、基本的には日常に取り入れる方が戦略的には効率が良いと考えています。ちゃんと確保しているかをチェックしてみてください。

https://kakehashi-dev.hatenablog.com/entry/2023/12/10/090000


## なぜこの５つのプラクティスを選んだのか？

1. すぐに始められる
    - 手で集計しても見える化できるレベルのため、決めるだけで始めることが出来る
    - ずっと続けるかどうかは別にして、データが欲しいときにすぐに試すことが出来る
    - 大きな仕組みがなくても出来るし、プロセスを作り込めば自動でも出来る
    - ユニットテストなどはマネージャの承認などは必要なく、現場エンジニアだけで始める事ができる
2. 何をすればよいか明確である
    - この領域は柔軟に対応するために抽象化されたプラクティスが多いため、形だけで意味のないことが起きやすい
    - やることが明確であれば、新しいプラクティスでも経験者が居なくても実践が可能
3. ビジネスチームに価値が伝わる
    - 数値の意味や肌感は分からなくても、目標数値や数値の推移、数値の規模感は伝わる
    - 開発中の状態の悪化や改善の変化が見える様になる

# 開発生産性を維持するにはチームの最初こそ大事

- チームの立ち上げのとき
- 新しいメンバーがチームに参加するとき
- 新しい計画をチームが始めるとき
- チームで機能を開発を始めるとき

これらのタイミングがチームの文化の土台を決めます
これらの始まるタイミングですぐに適応出来るルールとして使ってもらい、開発チームの文化になると良いなと思います

この技術的負債を適切に扱えるようになるためのエビデンスエコシステムを作りたいです。

# まとめ

今回はあえて技術的負債で出てくる質についての良い、悪い、ついて議論しない観点で考えてみました。

ポイントとしては

- 会社の文化を土台として、別で開発の文化をつくることが大事
- 情報を維持するためのプロセスを作り込む
- システムを開発し続けるための、中長期目線で考える
- ビジネスメンバーが理解できる指標を作る
- 過去を理解できる記録をする

などを考えています。

これらはあくまで、自分の思いついた妄想ですので、まだまだ基準のプラクティスの取捨選択やブラッシュアップのアイデアを議論できると楽しいと考えています。

もし、感想などあればコメントなどで頂けると嬉しいと思っています！