On Monolith

ちょっと前に monolithic な Java のコードベースを小さいモジュールに分解する仕事をしていた。激しく相互依存しているコードベースを相互依存のないコードに治していく。Painful な仕事だった。

相互依存がクソである点に異論はない。一方でどのくらいクソかはそれほど自明でもない。たとえばよくある「テストができない」という主張。Mock ライブラリが発達した今や割となんとかなる。

小さい manageable な単位 (ライブラリとか) に分解できないという批判。それもまったくそうなのだが、一方でコードが manageable な範囲におさまっている限り存在しない問題でもある。そしてどのくらいのコード量を manageable を感じるかには個人やインフラの出来で差がある。

依存関係を管理するのはプログラマの仕事の大きな部分を占めている。それをサボるのはまったくひどい話だが、一方でサボると捗る可能性も秘めている。現代における monolithic なコードベースの代表たる Rails アプリ。ORM で join するとガンガン依存関係が発生しちゃうけど、それでいいというのが Rails の立場だった。Rails プログラマは依存管理を省ける身軽さを知っている。(あたしの理解雑すぎ?)

Monolith の住人にとって、その身軽さを捨て依存関係の重荷を背負うのは必ずしも納得のいく判断ではない。自分は色々な都合で monolith-to-modules の仕事をやっていたけれど、一部のチームメイトには苦い顔をされていた。いままで相互依存を気にせずガンガン仕事を進められたのに、ライブラリに分割されたせいで依存関係管理のための様々なオーバーヘッドを払わなければいけない。

彼らの感じていたのと同じ frustration を, Rails アプリを microservices にした人々は感じなかったろうか。とくにその開発者が Rails 大好きっ子だったとしたら、コードを Go だの Java だので置き換えようとか言われてもイヤだよね。たぶん。会社やめちゃったりしない?

モジュール化のオーバーヘッドは優れた抽象で払い下げることができることもある。でも優れた抽象とかしなくてよくね?根本にそういう考えがあると、それ以上ふたりは歩み寄れない。

Microservices とか小さなライブラリとか、自分はどちらかというと好きな側にいる。それが "正しいエンジニアリング" だとも思う。でも monolith 勢の言い分も少しはわからなくもないと思うようになったこの頃。