Railsの設計について思うこと
Railsと設計
Railsは、Active Recordを中心に据えてコードを書いていきます。そうなると、自然とテーブル設計に強く依存したアプリケーションになって行くので、アプリケーションが複雑になっていくとツライ!となることがあります。こういった、Railsのアーキテクチャそのものに対する議論はたびたび話題に上がります。
- Ruby on Railsの正体と向き合い方 / What is Ruby on Rails and how to deal with it? - Speaker Deck
- Railsは、あえて密結合な構造にすることで記述量を減らしているというお話
- 中/大規模開発のためのRails設計パターン - Qiita
- 冗長なクラス構成をとってコードの記述場所を細分化しようというアイディア
RailsとDDD
RailsでDDDした人の話
最近、ミノ駆動さんのDDD(ドメイン駆動設計)に関する発表が界隈で話題になりました。
#ginzarails 本日の登壇資料はこちらです
— ミノ駆動 (@MinoDriven) 2020年10月23日
「Railsで考えるドメイン駆動設計のコアドメイン」https://t.co/hTZBb4AC4R
ドメイン駆動設計は、アプリケーションの中心にDBなどのデータストアではなく、ドメインを持ってくるという設計方法です。ヘキサゴナルアーキテクチャを使って実装されることが多いようです。長期開発を主眼においた設計手法で、大規模プロジェクトではよく使われる設計手法です。
ミノ駆動さんは、Railsの300KLOCを超える大規模なモノリシックなアプリケーションをDDDでリファクタリングするというとてつもない問題に取り組まれています。尊敬します。実際どんなアーキテクチャにしているかについても記事を書かれているので気になる方はぜひ。
ドメイン駆動設計の比類なきパワーでRailsレガシーコードなど大爆殺したるわあああ!!! - Qiita
ミノ駆動さんの主張のうち、私がRailsの設計を考える上で重要だと感じるのは次の2点です。
hanami
では、rubyでDDDをやりたい人はどうすればいいのでしょうか? hanamiというruby製フレームワークがあります。railsからこちらに乗り換えるべきでしょうか?
ここで、一度立ち止まって考えたいことは、いきなりDDDにゆくべきか?という点です。
偉い人はなんていっているか
エンタープライズアプリケーションの大家Martin Fowlor先生は、Railsのようなアクティブレコードを使った(所謂)犠牲的アーキテクチャと、Springのようなデータマッパーを使ったヘキサゴナルアーキテクチャはどっちがいいんだ?という議論を2014年に公開しています。時間が経ってはいますが、議論されているの対象となるRailsの性質は変わっていないため、現在でも十分聞く価値があります。
ものすごくざっくり要約すると下記のようなことを言っています。
- データマッパーとアクティブレコードの間にはトレードオフがある。データマッパーは複雑だがDBとの依存を低くでき、アクティブレコードは単純だがDBに強く依存する。
- ドメインが複雑で、アプリケーションとDBを分離する必要があるならヘキサゴナルアーキテクチャを使うべき
- ドメインが単純ならばActive Recordが有効に働く
- 判断基準となるのはドメインの複雑さであって、コードの量やテーブルの数ではない。ThoughtWorksで1000テーブル以上を扱うRailsアプリケーションが開発され、うまくいっていた。
Railsは、主に初期開発時のスピードをつけるために大変有効に働きます。設計が複雑になるからと言ってその利点をすんなり諦めてしまうのはもったいないように感じます。
スケールする設計
成功したプロダクトでは、長期的に見るとソフトウェアはこのような扱いを受けます。
- 立ち上げる
- 拡張する
- リプレイスする
Railsは、1. のフェーズにおいてはとても有効に機能します。 私がRailsのプロジェクトに関わっていて感じるのは、2. のフェーズをうまく過ごすことができれば、いきなりDDDを導入してアーキテクチャをごっそり入れ替えるみたいな大規模な回収を入れずに済むのではないか?ということです。
DDDにすれば解決する?
ヘキサゴナルアーキテクチャやDDDが良い、とされているのはアプリケーションの複雑さをアーキテクチャで吸収することでコードが単純になるから、と私は考えています。大げさに言うと、コードが単純になる代わりに、クラス設計や依存するライブラリの方に複雑さを寄せているに過ぎない、という考えです。
であれば、最初から複雑でないアプリケーションを構築するために、冗長なコードを書く必要があるのでしょうか?もちろん、最初から大規模だったり複雑になることがわかっていて、お金と人員が豊富なことがわかっているプロジェクトであればDDDを導入すべきだと思います。
管理が辛いのはRailsのせい?
Railsは、アーキテクチャに関する選択はプログラマーに委ねられている部分が少なからずあります。コントローラーとモデルの間に、どれたけクラスを配置しようが自由です。究極的には、Active RecordをDDDでいうRepositoryの実装として扱えば、Active Record、ひいてはDBへの依存を取り除き、ドメインをDBから隔離することもできます。
アプリケーションが複雑になってきたら、部分的に冗長なクラス構成に拡張していく、というようにスケールしてやればRailsでも大規模かつ複雑なアプリケーションを十分構築可能なのではないか、ということです。
最強のRailsの設計とは、自分達のアプリケーションにとっての最適を目指すこと
Railsは、普通に使っていくと柔軟性が低い。でも、最初のうちはそれでいい。アプリケーションが複雑になってきたら、その複雑さを吸収できるようなアーキテクチャに少しずつ変えていけばよいのでは、というお話でした。