インターフェイスと現実世界の感覚

数日前に通報の仕組みをつくっていた。
ユーザーが投稿に対して通報する仕組み。

Report(通報)はUser(ユーザー)とEntry(投稿)のユニークな組からなる。ある投稿に対して同じユーザーが複数回投稿することはできない。

ビューで「あるユーザーがこの投稿を通報したかどうか」返すメソッドをどういうインターフェイスにするかで悩んだ。

案1
ユーザーにたずねる。

kitak.reported_to? @entry

案2
投稿にたずねる。

@entry.reported_by? kitak

案3
レポートにたずねる。

Report.exists?
  entry: @entry, reporter: kitak

案3は、これまで@entryとkitakしかいなかった世界に新しいモデルのReportがでてきて複雑さが増すのでボツ。

僕は案1がいいと思った。
通報した本人にたずねるのが一番だ。
だけど、あんちぽさんにこう返されたのだった。
「君は現実世界でだれかに質問して、100%本当のことを教えてもらえると思っているのかい?」

結局、案2になった。

僕は、その機能の開発者で、ユーザーや投稿について把握している。だから、それらのリソースを当たり前のように信用している。
だけど、新しくコードを読む人は、その中がどうなっているのかはまったく分からない。インターフェイスから推測するしかない。
僕はそもそも現実世界に疎いのもあるけど、実装の内部を知っていると、このような現実世界の感覚とかけ離れたコードを書いてしまう。

現実世界の感覚をもってインターフェイスを決める僕と裏側でどのようにそれを実現するのか整合性を取るのか考える僕の2つの僕が要求されている。

テスト駆動開発は、その2つの僕をうまく切り替えながら、開発ができる手法だ。
テストを書くときは、インターフェイスを決める僕ががんばる。
テストを一回落としたら、もうひとりの僕が出てきて、そのテストを通すように裏側のことをあれこれ考える。
テスト駆動開発で、「なぜ落ちると分かっているのに一度テストを落とすのか?」という問いがあるけど、僕は、これをもうひとりの僕と切り替えるための儀式みたいなもんだと思っている。

10