簡単にするという最も難しいこと
It is better to do the right thing wrong than the wrong thing right.
ラッセル・エイコフは、間違ったことを正しく行うよりも正しいことを間違って行う方が良いと述べています。
これは私たちが間違ったことを行い、その過程で間違いを犯して修正をしたとしても、より間違った方向に進んでしまうということを意味しています。
はじめに
プロダクト開発において、Simplicity(シンプリシティ)は非常に重要な要素です。
多くの人が、「この機能は複雑そうだけど導入すればきっとうまく行きそう」「新しい機能を追加すれば複雑にはなるけどなんか良くなりそう」といった形で目の前に掲げられた目標を正しく作業することに没頭し、結果としてプロダクトが複雑化してしまったという経験があるのではないでしょうか?
一度複雑になってしまったプロダクトから複雑性を取り除くことは非常に難しく、またプロダクトが成長するにつれてより簡素化することが非常に難しくなります。簡単にするという最も難しいこと。この記事では、Simplicityの重要性と、Simplicityを保つことの難しさについて考察します。
Simplicityとはなにか
Simplicity
1. the fact that something is easy to understand or do
何かが理解しやすい、または行いやすいという事実
2. the fact that something is ordinary, traditional, or natural, and not complicated
何かが普通、伝統的、または自然であり、複雑でないという事
3. the fact that something is plain and has no decoration
何かが平凡で装飾がないという事実
Simplicityとは、単純であることであり、簡単であるということでもあります。
複雑化しがちな課題
プロダクト開発において複雑化しがちな課題は多数存在します。以下に非常によく見かける例をいくつか紹介します。
不必要なステップや操作の追加
顧客がサービス上で目的を達成するために、不必要なステップや操作を要求すべきではありません。顧客体験の視点から見て無駄な手順を排除することはサービス利用を促進すための重要な要素です。また、システム開発の観点でも無駄なステップや条件分岐が増えることは、開発速度を遅くし、メンテナンスコストを増やす要因となります。
複雑な契約体系
顧客向けの契約やプランの分岐が最小限であり、理解しやすい形であるべきです。契約体系が複雑な場合、顧客がサービスを利用する際に混乱を招くだけでなく、サポートやカスタマーサクセスの負担も増えてしまいます。また、契約ごとに制約条件やフック処理を入れるなど、システム開発の観点からも複雑さが増す要因となります。
複雑な前提条件
ある機能を利用するために必要な前提条件は最小限であるべきです。例えば、便器な機能Xを利用するためにはAとBという条件が必要である、というように複数の前提条件を掛け合わせたビジネスロジックの設計がしばしば行われます。前提条件が多くなると、システム全体のメンテナンスコストが増えるだけでなく、顧客や運用者にとっても理解しづらく、運用が困難になるリスクがあります。
不必要な機能追加
価値を提供するために、真に必要性がない機能や仕様を追加すべきではありません。それぞれの機能に対してテストやメンテナンスが必要になります。また、追加した機能は将来的に削除が難しくなり、システムの複雑さが減りにくくなります。
これは間違ったことを推し進め途中で気づいて修正してもより悪い結果になるという具体例です。
限られた顧客への対応
特定の顧客のために過度なカスタマイズや条件分岐を追加すべきではありません。特定の顧客に対応するためのカスタマイズが多い場合、それぞれのカスタマイズに対してテストやメンテナンスが必要になります。
過度な技術採用
使用するライブラリやフレームワークが多すぎたり、過度に大きなものを導入すべきではありません。ひとたびライブラリやフレームワークが導入してしまうと、それらを長期的にメンテナンスすることが非常に困難になります。使用する技術が過度に大きい場合、システムに不必要な機能も多く、システム全体が不必要に複雑化することもあります。
未来に対する過度な対応
不確定な未来の要件を見越して、過度な抽象化や拡張性の追加をすべきではありません。過度な抽象化や拡張性を持たせることは、開発速度を遅くし、メンテナンスコストを増やす要因となります。例えば、まだやるか決まっていない企画に対してあらかじめ拡張しやすい設計をしておくなどです。その企画はいつ具体化されるのでしょうか?具体化された時は想像していたものと全く別のものになる可能性もあります。
過度なインフラストラクチャ
機能を実現するためのインフラストラクチャが過度に提供されるべきではありません。インフラストラクチャが過度に提供されている場合、金銭的なメンテナンスコストが増えるだけでなく、開発速度も遅くなります。
捨てることの難しさ
複雑化しがちな課題に気づかず、間違った方向に大きく進んでしまった場合、後から単純化することは非常にむずかしいです。捨てることは作ることよりもはるかに難しい課題です。
執着
時間をかけて築き上げたコードや、長年使用してきた運用プロセスに執着することで、それを捨てることに抵抗感が生じることがあります。短い間でも残しておく判断をしてしまいがちです。私の経験から述べると、そのような理由で残しておいたものの多くは、将来的にも障壁となったままずっと放置されることが多いです。
将来への過度な期待
「いつか必要になるかもしれない」という考えは不要な機能を捨てられない原因となります。例えば今の判断ではこの機能をOFFにするが、いつか元に戻すかもしれない。いいえ、ほとんどの場合、その「いつか」は訪れません。たとえ必要になったとしても、その時には別の良い方法が見つかるはずです。
顧客離れへの恐れ
特定の顧客のニーズに対応するために追加した機能を削除することは、顧客離れのリスクを伴います。しかし、プロダクトの価値は、限定された顧客のニーズに応えることではなく、より多くの顧客のニーズに応える機能を提供することであるべきです。
複雑になってしまった仕様
仕様が大きいものほど、複雑性も増しています。あとから不要となった仕様を排除しようにも、影響範囲や仕様同士の依存関係も発生し、簡単には取り除けない状態になりがちです。
まとめ
私もしばしば複雑なビジネスロジックを設計したり、単純でない仕様をシステムに組み込もうとしてしまうことがあります。しかし、一度複雑になってしまったプロダクトから複雑性を取り除くことは大変な痛みを伴います。可能な限り最初の段階から、不要なものを捨ててSimplicityを保ち続けることが重要です。
迷ったときはシンプルな方を選択しましょう。