PHPの現場#27を聴いた / interfaceについて

面白かった。最近ぜんぜんPHPは書いてないんですが。

php-genba.shin1x1.com

感想書かなきゃとおもいながらダラダラしてたらもう次のエピソードが出ていたんだけど、1つ前のエピソードの感想です。

いろんな過程を経て、@shin1x1 さんの伝えたいことが熟成されてきている感じがして良い。

途中、interfaceを書くかという話で意見が分かれていた。僕も @shin1x1 さんと同じで、interfaceを使うことに特別な感情はない。

僕も昔はinterfaceを何のために書くのかわからなかったけど、今は「とりあえずinterfaceにしておいて、classでもいいかと思ったらclassにしよう」くらいの感じに思っている。これはきっと僕がOutside Inなプログラムの書きかたをするようになったからだと思う。いま自分が実装しているのはもちろんclassだけど、「そのclassが使っている何か」はinterfaceであろうがclassであろうが単体テストを書いている時点ではどちらでもいいし、そのとき再利用するかどうかは気にしない。

interfaceを何のために書くのかわかっていなかったころの僕は、interfaceというとFooInterfaceというインターフェースに対してFooImplみたいな実装があるみたいなイメージを持っていて、これって何の意味があるのって思っていた。でも、インターフェースと実装は1対1ではない。

f:id:iakio:20190226214528p:plain

phpspecで学ぶLondon School TDD

上のスライドは、Markdown#toHtmlFromReaderというメソッドの引数に渡すのはFileStorageクラスとReaderインターフェースのどちらが良いかという話(この例はphpspecのドキュメントを参考にさせてもらった)。Markdown#toHtmlFromReaderの単体テストを書いている時点では、それを動かすために最小限必要なものをモックする。その方が、意図を正しくコードに反映できると思っている。

僕がプログラマーとして最も影響を受けた読み物の1つは、平鍋さんが2005年に書いた次のブログエントリーだ*1

  • 「テストしやすい」ことが、良い設計(EoT=Ease of Testing):An Agile Way:オルタナティブ・ブログ

  • ぼくは、

    EoT(*1)の高い設計が、よいオブジェクト指向設計である。

    と主張する。設計品質の中で「テスト容易性(EoT)」を最上位と見るのだ。オブジェクト指向のさまざまな機構、用語、考え方は、すべて EoT のため、と捕らえられる。

    僕は「オブジェクト指向とは / interfaceとは / DIとは何か」ということは説明できないけど、それらを何のために使っているかは説明できる。それはテスト容易性のためであり、言いかえれば、「今書いたコードをすぐに動かしてフィードバックを得る」ためとも言える。素早くフィードバックを得るためには、動かすのは大きなコードより小さなコードの方が良い。そのために、大きなコードのほんの一部だけを切り出して動かす方法が必要となる。僕にとってオブジェクト指向やinterfaceやDIは、そのための道具だ。

    オブジェクト指向やinterfaceやDIの話をするときにしばしば再利用性の話がとりあげられる。例えばDIを使えば永続化レイヤーを別のものに差し替えられる、みたいな。でも実際差し替えることなんてそうはおきないんのではないだろうか(まあ無くはないんだけど)。

    でも、あるコードの一部分を、プロダクションコードとしても単体テストとしても動作するようにデザインするということは、それはある意味「再利用している」と言える。僕はこの意味での再利用の方が重要だと思っている。

    もっとも、僕がこのエントリーに強烈なインパクトを受けた理由は、2005年という時代が、前者の意味での再利用性が強調されがちだった時代だったからなのかもしれない。そしてその意味を本当に理解するのは、それから何年も経ってからだった。