開発速度と品質のトレードオフの判断基準の合意

Webサービスの開発は、ユーザ/顧客へ価値を早く届けるため、競合より早くリリースするため、人的リソースを無駄使いしないためなど、とにかく素早く進めたいものですね。一方で、開発を急ぐあまり品質を犠牲にすればかえって価値が失われたり、技術的負債が溜まって長期的なコストが大幅に増大する可能性もあります。開発速度とプロダクト品質は基本的にはトレードオフの関係にあるのでしょう。

開発速度と品質のどちらを優先するかはプロダクトの性質や、チームもしくは会社の状況によって異なるとおもいます。この状況の認識がチームメンバー間でずれていると、チームのパフォーマンスを最大限に発揮できないばかりか、チーム内の関係悪化も招きかねません。エンジニアたちとプロダクトオーナーの間の対立のようなありがちな問題の原因の一つかもしれません。

そこで、開発速度と品質のトレードオフをどう判断すべきかの基準を明確にして、原則それに従うことをあらかじめチーム内で合意してみました。

この記事は、はてなエンジニアアドベントカレンダー2016の24日目で、担当はid:taraoです。昨日の担当はid:takuji31さんのAtomの自動補完プラグイン「autocomplete-plus」のPerl用Providerを書いている話でした。

経緯

同じWebサービスを長く提供し続けてきたこともあり、近頃のはてなでは技術的負債を残さないためにはどうすべきかという問題意識が高まり、品質に敏感になっていると感じています。そんな中で、チームのプロダクトオーナーから、「開発速度を上げるために犠牲にしてよいコード品質の判断基準を明文化してほしい」という相談を受けました*1。チームメンバーが増えてきた時期で、効率的な開発を進めるための課題を感じていたところだったからです。

他のチームからも、「品質向上のために技術的な議論を尽くすのはいいが、あまり重要でない部分の議論にまで時間をかけすぎてしまっている」「きちんと設計してから実装に着手したり、コードレビューを事細かにやるのはいいが、スピード感がなくなっている」という声が聞こえました。

ひとまず自分のチームの状況に合わせた判断基準を書き出してみたところ、一般的な話がほとんどだったので、似た問題を抱えたチームにも共有してみました。すると「これは社内に限らない話なので公開したらどうか」と提案を受け、この記事を書くに至りました。

目標設定

まず、とにかく早く作ればよいのではなく、どうあるのがゴールなのか/理想なのか、ということを決めておくと、基準がぶれずに済むのではないかとおもいます。このゴールはチームの状況によって違うはずです。僕らのチームは、プロトタイプを手早く作ってよりよい仕様を探っていくのではなく、実現すべきものがはっきりしていて、それでいてスケジュールはある程度まで融通が利き、ただ早くできるよりは今後10年単位できちんとメンテナンスしていけるものを作るのが目的だったので、以下のようなゴール感を設定しました。

  • 5年後、10年後に破綻しないプロダクトにする
    • よくない部分を改修していくことでよい状態を保ち続けられるようにする
    • プロダクトの成長に合わせてスケールできるようにする
    • より挑戦的な機能を将来的に実装できるような余地を残す
  • 将来発生しうるコストを下げる
    • 新規メンバーの導入コスト
    • 新機能の開発コスト
    • メンテナンスコスト

目標が設定できたら、具体的なアクションプランにブレークダンしてみます。たとえば「新規メンバーの導入コスト」を下げるために「ドキュメントやチュートリアルを充実させる」「新しいメンバーにはメンターが張り付く」といったものです。アクションプランすべてを常に完璧にこなすには時間がいくらあっても足りないので、どういう場合には手を抜いてよいかを、真に達成したかった目標に照らしながら考えていくと、トレードオフの判断基準ができるとおもいます。

判断基準

本当は目標に関わるすべてのアクションプランに対して検討した方がよいとおもいますが、ひとまず実際の開発タスク(設計や実装)をこなす上で、品質をどれくらい優先すべきかわかるようにしたい、というのがプロダクトオーナーからの相談の意図だったので、その観点で絞って考えてみました。

判断対象優先度内容
設計全体アーキテクチャなど根幹に関わる部分
ドメイン層の定義
コア機能
コア寄りの機能
その他の機能
独立性が高くサイズが小さい機能
疎結合性大きな機能
小さい機能
パフォーマンス悪化するとサービスが停止するような部分
利用者へのインパクトが大きい機能
状況に応じてコストをかければ向上が見込める部分

設計コストとのトレードオフ (優先度が低ければ雑な設計でもよい)

基本的にはのちに大きな影響が出そうなところはしっかり設計しておくとよいでしょう。全体アーキテクチャやシステムの土台部分は言うまでもなく重要です。ドメインモデルもしっかり議論しながら常に最高の状態に保つ努力をしていかないと、自分たちが何を作っているのかもあやふやになってしまうので非常に重要です。

その機能なしにはプロダクトが存在できないようなコア機能は、一番重要な機能のはずなのでしっかり設計しておくべきです。コア機能とは呼べないまでも、他の多くの機能から依存されている機能はコア寄りの機能といってよいでしょう。独立性が高ければあとで変更しやすいので優先度を低く設定できますが、その分、疎結合に保つためのコストがかかります。

疎結合性とのトレードオフ (優先度が低ければ疎結合性を高めなくてもよい)

大きな機能が他のあらゆる機能と密結合している状況はできる限り避けたいので、まとまった大きな機能になるほどサブシステムとして追い出した方がよいかもしれません。ただし、サブシステムがもはやサブとはいえない大きさになってしまうと困るので、限度はあります。たとえば、どんなに大きくても2人で3ヶ月〜半年で作りなおせるくらい、など具体的な限度を決めておくとよさそうです。この限度を超えそうな場合は別のチーム/システムとして切り出すことを相談すべきということになります。

逆に、それほど大きな機能でなければコード上で適切なモジュールに閉じているという程度の疎結合性で十分でしょうし、疎結合性にこだわったところでインパクトも小さいのでひとまず後回しにして、機能が大きくなってきたら再度サブシステム化を検討すれば十分でしょう。

パフォーマンスとのトレードオフ (優先度が低ければパフォーマンスを気にしなくてよい)

プロダクトが存続できるかどうか、ユーザへの価値を発揮できるかどうかを揺るがすようなパフォーマンスの劣化は当然許容できません。ある機能のユーザへの価値提供の度合いには、その機能を利用しているユーザが多いかどうか以外にも、ユーザがそのプロダクトを選ぶ理由になっている(差別化要因になっている)かどうかなども関わってくるでしょう。

最初の段階では及第点のパフォーマンスだっとして、ユーザが増えたときのことを考えるともう少し賢い(けれど複雑)なしくみでスケールできるようにしておきたい、という気持ちもあります。こういう場合、どうすればスケールさせられるかの見通しがはっきりしていて、あとから改修すれば済むのであれば、後回しにする決意も大事です。開発速度の点でもそうですが、無用な複雑化を避けるという点でも必要なことです。

判断基準の利用

このような基準を設けておくと、まずプロダクトオーナーとのやりとりがスムーズになります。たとえば「この機能はコア機能なので、設計をきちんとしたいし、企画面に関わる相談も密にやりたいから、十分な時間をとってほしい」「まずはパフォーマンスはほどほどで速度優先で実装していくので、マイルストーンごとにパフォーマンスチューニングの期間を設けてほしい」といったことを伝えやすくなります。あるいはメンバー間でも有用で、たとえばコードレビューで「ここはイケてないからもっとこうするべき」という議論が白熱しだした場合にも「判断基準によればひとまずそこまでのインパクトはないから開発速度を優先していったんこのままでいきましょう」という妥協がしやすくなります。

実際にあった例としては、コード品質はいったん犠牲にしてタスク消化を優先する代わりにマイルストーンの終わりにリファクタリング期間を設けることにして、実際にリファクタリングに着手する際には、プロダクトオーナーとテックリードとスクラムマスターがこれらの判断基準に従って協議して、着手すべきタスクの優先順位を決めていきました。こうして決まった優先度の高いタスクは、他のチームメンバーにとっても重要度がわかりやすく実際に完了時のインパクトも大きいので、達成感をもってとり組めたのではないかとおもいます。

おわりに

ここで挙げた判断基準は経験豊富なエンジニアであれば自然と持っている感覚で、あえて明文化するまでもないかもしれません。けれど、あたり前とおもっていることは案外あたり前ではなかったりします。駆け出しの新人がチームに入ってきた場合や、エンジニアリングの経験のないプロダクトオーナーとやりとりする場合には、自明とまでは言えないのではないでしょうか。むしろ当然とおもえばこそ、そんな経験豊富なエンジニアがテックリード的な立場で基準を考えておくとよさそうです。

繰り返しになりますが、どのような判断基準を設けるかはチームの状況によって変わってくるとおもいます。みなさんも是非ご自身の状況に合わせて考えてみて、可能なら「こういう状況ではこういう基準がよさそうだ」というのを公開してみてください。

アドベントカレンダーの明日の担当はid:funnelbitさんです!

*1:実際にはこんなに明快に言われたわけではなく、プロダクトオーナーとやりとりを繰り返して問題意識を整理した結果、判断基準が明文化されていればよいという結論に落ちついた形です