「Railsやってる人たちってドメイン層にvirtusとかinteractorとかサードパーティのライブラリが現れるのってどう思ってんの」という雑なツイートに対してROM.rbやdry-rbシリーズの作者であるPiotr Solnicaが優しくリプをくれた。
One rule of thumb is to rely on your own interfaces, even if it means having a small wrapper around a simple 3rd-party API. This is what gives you more control, and this is what makes it much easier to upgrade gems along the way once something stops working (for whatever reason)
— 🤘🏻Piotr Solnica🤘🏻 (@_solnic_) March 30, 2020
絶対に守らねばならないルール、それは「常に固有のインターフェイスに依存する」であるとのこと。
いくらシンプルなGemであっても、必ずGemのインターフェイスとなるラッパーを用意すること。ラッパーを用意することで、そのGemの機能を使う側のモジュールは、ラッパーのインターフェイスのみに依存させることができる。そうすればGemがdeprecatedになっても、容易に自前で作ったものに差し替えたり、代替となるGemで入れ替えたりできる。
これは本当に間違いない。この観点から言えば、ラッパーとなるオブジェクトはできるだけサードパーティのGemの機能を抽象化したインターフェイスとなるべきだ。しかし、どこまで未来の設計を考えて抽象化するか、というのはすごく匙加減が難しいところではある。
When it comes to dry-rb, we've been trying to design these gems to be unobstrusive and provide functionality that you can reuse to implement so called "domain components". There's no dry-rb gem that would provide any specific domain component. Everything's generic functionality.
— 🤘🏻Piotr Solnica🤘🏻 (@_solnic_) March 30, 2020
dry-rbの作者としては、dry-rbシリーズはunobstrusive(邪魔にならない)ようにデザインしているらしい。
具体的に「どう邪魔しない」のかは分からないが、最後にSolnicaが言うように「ジェネリックな機能」だけを提供することで、dry-rbそれ自体がドメインそのものにならないようにしているのだとは思う。
たしかに、サードパーティのGemが現れるとしても、それがよほど突飛なインターフェイスを提供していない限り、用意に別のGemに乗り換えることが可能だし、仮に突飛だとしてもラップして自前のインターフェイスによる利用だけに限定してしまえばある程度は依存をコントロールできるだろう。
この手の依存をコントロールする系の話は「オブジェクト指向設計実践ガイド」にも書かれていた気がする。
オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方
- 作者:Sandi Metz
- 発売日: 2016/09/02
- メディア: Kindle版