私がソフトウェア開発において心がけていることの一つに「設計に悩み始めたらとりあえず手を動かす」というものがあります。今まで深く考えずにそう心がけていましたが、この記事で自分がなぜそうしているのか整理して言語化してみたいと思います。

話のスコープ

ここでいう「手を動かす」とは「コードを書く」ことです。設計と聞いて人によって思い浮かべるものが違いますが、ここでは「一人のソフトウェアエンジニアが四半期程度かけて開発する規模の機能の設計」を想定しています。何人ものソフトウェアエンジニアが長期に渡って行うような大規模開発には当てはまらないです。

本題

次のような経験はないでしょうか?

設計を考えながらデザインドキュメントを書いていたら細部の粗が見えてきて無限に悩み続けてしまった。考えなきゃいけないことがどんどん膨らんでいって、いつまでも実装に手を付けられなかった。

これに対して私は「設計に悩み始めたらとりあえず手を動かす」を意識し、設計の大枠が見えたら細部を詰める前に手を動かしてコードを書き始めるようにしています。その理由を内省してみると次のようになりました。

  • 詳細設計まで先にじっくり考えるとめんどくさい部分が目についてなかなか手が付けられなくなる。コードを書き始めながら考えると初速がある分めんどくさいこともやり遂げやすい。
  • ワーキングメモリを空けられる。実装方針が明らかな部分も実際に実装するまでは頭の片隅においておかなくてはいけない。設計を実装レベルの解像度で頭に載せ続けるのは大変。手を動かしてさっさと実装してしまえばその部分は脳内からごっそり落とせるので、考えるべき範囲をコンパクトにできてワーキングメモリに載せやすくなる。このときついでにベースとなる既存実装のリファクタリングも積極的に行う。既存実装の見通しが良くなるとその上に作る新機能の設計負担が減るし、コードを変更したことで既存実装に対する理解も深まる。これが実装ベロシティの向上につながる。
  • 実装済みの部分に対してコンパイラやテストによるフィードバックイテレーションを回すことができる。これにより特定のプラットフォームでしか起きない問題や実装しないと分からないような問題に気づきやすくなる。結果として設計の解像度を上げることができる。
  • たとえ不完全でも早めに動くものを用意することで、時間的・精神的な余裕が生まれる。
  • 書いたコードが無駄になるかもしれないが、たいてい二回目の方がうまくすばやく綺麗に書けるので大きなロスにはならない。別アプローチの試行例としてデザインドキュメントに残すこともできる。書いたコードが無駄になるのを恐れる必要はない。
  • デザインドキュメントだけしかない場合に比べて、コードがある方がチームメイトからのフィードバックの精度が上がる可能性がある。一方で細かいところまで見えすぎてしまうため、本質的じゃない部分にフィードバックが集中してしまう可能性もある。WIP である部分はコメントなどで明示し、レビュアーに対する期待値を適切にコントロールする必要がある。

なお詳細な設計やデザインドキュメントの重要性を低く見ているわけではないです。むしろこれらは可能な限り早い段階で明文化されるべきと考えています。一方でそれらは実装開始をブロックするものではなく、むしろプロトタイプを通して育てていくものだと考えています。

ちなみに私はコードを書きながらじゃないとデザインができないので、プロトタイピングしながら Design Doc を書くというスタイルを取っています。Design Doc が書き上がる頃には大体動くものができていて、議論を通してこのプロトタイプを叩き上げて完成形にします。

Design Docs への思い - Design Docs を書く目的

私自身は Design Docs は育てるものだと思ってるので、プロトタイピングや議論をしながらガシガシアップデートしています。

Design Docs への思い - 設計詳細を含むか?

ここまでを書きながら気づいたんですが、これは以前書いた「チームにいると頼りになるソフトウェアエンジニア」の「突破力」に関係するものですね。こういった心がけは周りの頼りになる同僚諸氏の影響を強く受けて醸成されたのかもしれません。

突破力

依存関係や後方互換性が複雑に絡まっているプロジェクトにおいて、細かいことを気にせずとりあえず動く巨大なパッチを速攻で書き切ってレビューを投げてくるタイプの人。コードマニアやマインスイーパは細かいところが見えすぎて設計議論の段階で手が止まりがちだが、このタイプの人はとりあえず動くものを作って突破口を切り開いてくれる。パッチは荒削りだが叩き台として具体的な話を進められるようになる。見えていなかった問題点が見えるようになったり、実は簡単に解決できることに気づいたりする。

Chromium のような超巨大なモノリスでコードを書く場合は、こういう突破力のあるエンジニアが一人チームにいるとプロジェクトが一気に進む。特にプロジェクト初期の不確実性を減らす上で貴重な存在。

チームにいると頼りになるソフトウェアエンジニア - 突破力

まとめ

この記事では「設計に悩み始めたらとりあえず手を動かす」という心がけについて言語化してみました。自分が経験的に身につけ、感覚的に実行してきたことをうまく整理できた気がします。また自分が思い描く「頼りになるソフトウェアエンジニア」の特質にもつながっていることに気づきました。