マイペースなRailsおじさん

Ruby、Ruby on Rails、オブジェクト指向設計を主なテーマとして扱います。だんだん大きくなっていくRuby on Rails製プロダクトのメンテナンス性を損なわない方法を考えたり考えなかったりしている人のブログです。

Railsの設計について思うこと

Railsと設計

Railsは、Active Recordを中心に据えてコードを書いていきます。そうなると、自然とテーブル設計に強く依存したアプリケーションになって行くので、アプリケーションが複雑になっていくとツライ!となることがあります。こういった、Railsアーキテクチャそのものに対する議論はたびたび話題に上がります。

RailsとDDD

RailsでDDDした人の話

最近、ミノ駆動さんのDDD(ドメイン駆動設計)に関する発表が界隈で話題になりました。

ドメイン駆動設計は、アプリケーションの中心にDBなどのデータストアではなく、ドメインを持ってくるという設計方法です。ヘキサゴナルアーキテクチャを使って実装されることが多いようです。長期開発を主眼においた設計手法で、大規模プロジェクトではよく使われる設計手法です。

ミノ駆動さんは、Railsの300KLOCを超える大規模なモノリシックなアプリケーションをDDDでリファクタリングするというとてつもない問題に取り組まれています。尊敬します。実際どんなアーキテクチャにしているかについても記事を書かれているので気になる方はぜひ。

ドメイン駆動設計の比類なきパワーでRailsレガシーコードなど大爆殺したるわあああ!!! - Qiita

ミノ駆動さんの主張のうち、私がRailsの設計を考える上で重要だと感じるのは次の2点です。

  • 初めからRailsでDDDをやるのはおすすめしない
  • コアドメインに対して部分的にDDDを導入すると良いのではないか

hanami

では、rubyでDDDをやりたい人はどうすればいいのでしょうか? hanamiというrubyフレームワークがあります。railsからこちらに乗り換えるべきでしょうか?

hanamirb.org

ここで、一度立ち止まって考えたいことは、いきなりDDDにゆくべきか?という点です。

偉い人はなんていっているか

エンタープライズアプリケーションの大家Martin Fowlor先生は、Railsのようなアクティブレコードを使った(所謂)犠牲的アーキテクチャと、Springのようなデータマッパーを使ったヘキサゴナルアーキテクチャはどっちがいいんだ?という議論を2014年に公開しています。時間が経ってはいますが、議論されているの対象となるRailsの性質は変わっていないため、現在でも十分聞く価値があります。

www.martinfowler.com

ものすごくざっくり要約すると下記のようなことを言っています。

  • データマッパーとアクティブレコードの間にはトレードオフがある。データマッパーは複雑だがDBとの依存を低くでき、アクティブレコードは単純だがDBに強く依存する。
  • ドメインが複雑で、アプリケーションとDBを分離する必要があるならヘキサゴナルアーキテクチャを使うべき
  • ドメインが単純ならばActive Recordが有効に働く
  • 判断基準となるのはドメインの複雑さであって、コードの量やテーブルの数ではない。ThoughtWorksで1000テーブル以上を扱うRailsアプリケーションが開発され、うまくいっていた。

Railsは、主に初期開発時のスピードをつけるために大変有効に働きます。設計が複雑になるからと言ってその利点をすんなり諦めてしまうのはもったいないように感じます。

スケールする設計

成功したプロダクトでは、長期的に見るとソフトウェアはこのような扱いを受けます。

  1. 立ち上げる
  2. 拡張する
  3. リプレイスする

Railsは、1. のフェーズにおいてはとても有効に機能します。 私がRailsのプロジェクトに関わっていて感じるのは、2. のフェーズをうまく過ごすことができれば、いきなりDDDを導入してアーキテクチャをごっそり入れ替えるみたいな大規模な回収を入れずに済むのではないか?ということです。

DDDにすれば解決する?

ヘキサゴナルアーキテクチャやDDDが良い、とされているのはアプリケーションの複雑さをアーキテクチャで吸収することでコードが単純になるから、と私は考えています。大げさに言うと、コードが単純になる代わりに、クラス設計や依存するライブラリの方に複雑さを寄せているに過ぎない、という考えです。

であれば、最初から複雑でないアプリケーションを構築するために、冗長なコードを書く必要があるのでしょうか?もちろん、最初から大規模だったり複雑になることがわかっていて、お金と人員が豊富なことがわかっているプロジェクトであればDDDを導入すべきだと思います。

管理が辛いのはRailsのせい?

Railsは、アーキテクチャに関する選択はプログラマーに委ねられている部分が少なからずあります。コントローラーとモデルの間に、どれたけクラスを配置しようが自由です。究極的には、Active RecordをDDDでいうRepositoryの実装として扱えば、Active Record、ひいてはDBへの依存を取り除き、ドメインをDBから隔離することもできます。

アプリケーションが複雑になってきたら、部分的に冗長なクラス構成に拡張していく、というようにスケールしてやればRailsでも大規模かつ複雑なアプリケーションを十分構築可能なのではないか、ということです。

最強のRailsの設計とは、自分達のアプリケーションにとっての最適を目指すこと

Railsは、普通に使っていくと柔軟性が低い。でも、最初のうちはそれでいい。アプリケーションが複雑になってきたら、その複雑さを吸収できるようなアーキテクチャに少しずつ変えていけばよいのでは、というお話でした。