技術的負債の解消をする前の話

2022/12/24に公開

こちらの記事はmybest product dev Advent Calendar 2022にも参加しています。

https://adventar.org/calendars/8007

株式会社マイベストでバックエンドエンジニアをやってるgamiTaです。

本日はクリスマス・イブですが、もはや年末です。
そして年末といえば大掃除で、大掃除といえば…技術的負債の返済ですね!

技術的負債解消に関する重要性を説く話題は年に何度も上がってくるくらいホットです。
最近でも下記のようなスライドが話題になっていました。

https://speakerdeck.com/mtx2s/technical-debt-and-developer-experience?slide=8

上記のスライドでは技術的負債を「意図的・不注意」と「慎重・無謀」という、それを四象限に定義してそれぞれへの戦い方を挙げていました。とても参考になるスライドです。

しかしこのような技術的負債解消の重要性を説く記事を見てリファクタリングを実行する気持ちに駆られても、ちょっとした実装ついでにリファクタリングして負債を返済できるものなら良いですが、テーブル構造から変更するようなガッツリとしたリファクタリングを伴う返済は腰が重くなってしまうのは大掃除と同じです。

大掃除は気合を絞り出せば何とか実行にまで漕ぎ着けられますが、技術的負債は気合を入れてやろうとしてもそのリソースが開発チーム内で認められなければチケットを切ることがそもそもできません。切れても塩漬けされたままになると思います。

技術的負債解消に関する重要性がわかっていても、技術的負債を解決する技術があっても、まずチケットを切るところから始まるため、そのあたりの話を書いていければなと思います。

技術的負債を解消するリファクタリングのチケットを切るために

※ここでいうリファクタリングは新規機能の実装に合わせて既存機能をちょっとリファクタリングするという粒度ではなく、そのリファクタリングを行うだけで一つのチケットが切れる粒度を想定しています。

技術的負債を解消するリファクタリングのチケットを切るためには、プロダクトオーナー(ここでいうプロダクトオーナーは開発リソースを割り振る決定権を持つ人)はもちろん、開発チームのメンバーからの理解を得ることも大事です。リファクタリングの規模が大きければ大きいほどメンバーの協力が不可欠になるからです。
(※POの更に上にいるステークホルダーを納得させるのは一旦POの仕事として割り切って進めます)

そのリファクタリングを行おうとする前提の課題感が既に開発チーム全体で共有されていれば、チケットを切ることの理解を得ることは難しくないはずです。むしろ率先して課題感を持って片付けてくれることにプロダクトオーナーも喜んでリソース割いてくれるでしょう。
(※一定、技術的負債の返済に理解があるPOという性善説で進めます)

しかしその課題感が開発チーム内で共有されていなく、自分しか課題に思っていないとき。
まずその技術的負債の課題感を言語化し、そしてそれを開発チーム内への共有する必要があります。

課題感の言語化のためには

  • 現状のままであり続けることに対する具体的なデメリット
  • 解決したときに生じる具体的なメリット

の2点について記述するのがシンプルで伝わり易い言語化方法だと思います。

ここで具体的な話になってくるのですが、私が行った課題の言語化例を記載します。

前提として、私が所属しているマイベストのコンテンツ管理システムの機能の1つに「再編集機能」というものがあります。それは公開中のコンテンツに影響を与えることなく、公開中のコンテンツを元にした編集作業ができる機能です。編集作業中はその内容が公開中のコンテンツに反映されることなく、編集作業の完了後、その編集内容が公開中のコンテンツと入れ替わることで、まとめて編集内容を反映することができます。

この機能を実現するために、だいぶ簡易的に記述すると、コンテンツ用のAテーブルと再編集用のA'テーブルという2つのテーブルが存在し、再編集機能を動作させると、該当のAテーブルのレコードを元に再編集用のA'テーブルのレコードが作成されるという仕組みでした。Aテーブルには子テーブルも複数存在し、それも同様にA'テーブルの子テーブルとしてコピーされました。(Railsで言うところのポリモーフィック関連にすることで1つの子テーブルで2つの親テーブルを扱えるようにしていました。)
再編集側を公開する場合は、逆にA'の内容をAにコピーし、A'の子テーブルのリレーションはAに向くように変更し、その後A'は削除します。

当初はおそらく、再編集側独自の振る舞いや、再編集用以外のモデルの存在も想定されていたのかもですが、実際に運用すると振る舞い的にはコンテンツ側とほとんど同じであり、また新しい再編集以外のモデルも作成されることはありませんでした。

この状態における開発中の困ったこととしては

  • Aテーブルに紐づくAモデルを修正すると、同様にA'モデルも修正する必要が出てくるパターンがある(ある程度は共通化しているとは言え)
  • ポリモーフィックな構造による複雑性が実装中に顔を出してくるのが辛い
  • コンテンツ以外のコンテンツ種別がマイベストには存在するが、他のコンテンツ種別に再編集機能を追加しようとすると前例踏襲的に同じような作りになってしまいそう

でした。
なのでAモデルだけで完結するならAモデルだけで完結した方が開発体験が良いし、なんなら再編集という機能を外出して他のコンテンツ種別でも使えた方が良い…という課題感がぼんやりあったのです。

ここまでが前提です。
このぼんやりとした課題感の言語化のために、下記の方法に当てはめたいと思います。

  • 現状のままであり続けることに対する具体的なデメリット
  • 解決したときに生じる具体的なメリット
### 解決したい課題 = 現状のままであり続けることに対する具体的なデメリット
1. Aモデルを改修するときにA'モデルの影響も考慮する必要がある分、設計・実装に掛かる時間がそれぞれ最大2倍掛かる
2. A以外の記事種別ごとに0から開発しないといけない開発コストの高さから、再編集機能未実装のコンテンツ種別に再編集機能を追加する優先度が下がる

### 解決したときの価値 = 解決したときに生じる具体的なメリット
- 機能開発時、及びテスト作成時、Aモデルの考慮だけで済むので、設計・実装に掛かっていた工数も最大半分になる
- 再編集機能未追加へのコンテンツ種別への再編集機能追加実装が選択しやすくなる

このような言語化にあたっては、具体的な数値が記述できると、とても強い説得材料となります。

今回はシンプルにモデル数がそのまま開発実装コストに直結しているように書いていますが、日頃からチケットに費やした実工数と見積工数のブレの可視化、原因追求をしておくとより具体的な数値が記述できると思います。

具体的な数値があればあるほど、POもステークホルダーに対して説明がしやすくなるので(特に工数周り)、チケットが切りやすくなると思います。

また、技術的負債によって実工数が増えた要因をふりかえり等でチーム内で共有していくことで、チームとしても課題感が上がっていき、よりチケットも切る判断がしやすくなるでしょう。

その他

ちなみにマイベストでは、プロダクトの機能開発のリソースとは別に技術的負債等の課題を解決するためリソースが別途割り振られているので、課題解決はもはやする前提となっています。
開発チームとして目標を持つにあたり、プロダクトの機能開発関連だけを目標に持つと、こういった課題と付き合うのは大変だと思うのでとても良い目標の持ち方だと思います。

Discussion