「拡張性を考慮して」というワードをよく聞くが、その拡張する機会が訪れなかったり、想定していた拡張性と違っていたり、そもそも実装の筋が悪かったり、拡張性を考慮したことによりコードが保守しづらくなる、といった結果になったことも少なくない。
例えば、こういった経験をしたことがあったりする。
- 他の認証方式を追加するかもしれないからと思って拡張できるように作ったものの、認証方式は追加されなかった
- 拡張性を考慮して管理画面で変更できるパラメータを増やしたが、あまり使われなかった
- データストレージを切り替えるためのリポジトリ層を用意したがデータストレージを切り替える機会がないまま終わる
- ↑でデータストレージを切り替える機会があったもののリポジトリ層の抽象化の仕方が良くなくて、結局リポジトリ層を導入していないコードと同じくらいの労力がかかってしまった
- 拡張性を考慮して抽象に対して実装したが、その拡張性を使う機会が全くなかった
- 拡張性を考慮してマイクロサービスにしたが、その拡張が必要な規模にならず、分断されたモノリスになってしまったり、保守性が下がってしまった
ということで、拡張性を大事にしすぎるのも考えものだなぁと思っていたりする。 個人的にはそれよりもスピード感持って今の課題を解決していく方が大事なんじゃないかなとか思ったりしたので以下、駄文を書く。
その拡張性の効果が出るのは「いつ」か?
1〜2ヶ月以内くらいに機能実装する予定なのか、半年後くらいなのか、1年以上あとなのか、というのでも結構変わってくる。その拡張性の効果が出るのは「いつ」か、と言い換えても良いかもしれない。
たとえば半年後、1年以後の効果を見込んでいる場合には、状況がかなり変わっている可能性が高く、その拡張性のニーズも変わっているかもしれない。 逆に1〜2ヶ月以内であればそれなりにニーズが高い機能であり優先度としても高いため、拡張性を考慮した実装にしてもその実装が無駄になることは少ないように思う。
そのときに変更できるのか?という判断軸
その拡張に対応するときに現実的な工数で対応できるのであれば、「いますぐ」に拡張性のある実装をする必要はないかもしれない。その場合、ある程度実装方法のあたりを付けておいて「そのとき」が来たら一気に対応する、という感じになる。
DBに関しては変更がしづらい代表格なので、もちろんある程度拡張性を考えても良いのだが、現状で参照・更新箇所が少なかったり使われ方の拡張性が見えづらいテーブルに関しては過度に考える必要はないかもしれない。
データ数がそこまで多くなく、影響範囲なども含めたマイグレーションプランも立てやすいものであれば一旦管理が楽な方に振り切って、ある程度見えてきた段階で変更する感じがリスクが少ないように思える。
とはいえ、このあたりの判断の閾値はチームの経験や腕力に強く依存するということも付け加えておく。
いずれにしても実装時に 将来的な変更を予想してみて、それが来たときにどういう変更をすればよいのか
を考えるのが大事なように思う。
「変更できるようにする」するのではなく、「変更を想定しておく」だけで良い。
拡張性よりもスピード
ということで下手に拡張性を考えすぎて開発が遅れるよりは、拡張性は考慮しつつも現状の課題を解決するリリースをサクッとやってしまうのが良いと思っている。
そのリリースをすることでフィードバックが得られ、未来にやるべきこと=拡張の方向性が見えてくる。もし拡張が必要であればサクッとリリースしたことによって余った時間と想定していた変更方法を使ってサクッと拡張していけば良い。
言い換えると 決定を遅らせる
という話なんだけど、決定を遅らせるために抽象化して中小に対して実装するというような話ではなく、現在の課題を解決し、ちょっと先の不確実性の高い未来に対応できるためにも今やるべきことをうまくやっていきましょうという話なのかも。