Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

ActiveRecordモデルはいつ「太りすぎ」なのか?ロジックの置き場所を決める判断基準

Railsのブログや書籍、カンファレンスの講演を見ていると、モデルを「スリム」にするためのテクニックが数多く紹介されています。

これらのテクニックは確かに素晴らしいものです。モデルは必ず巨大化・複雑化して手に負えなくなる瞬間が訪れるからです。しかし、本当にそこまでやる必要があるでしょうか? モデルの責務を永続化・アソシエーション・バリデーションだけに絞り込みたいのでしょうか?そもそも、どれくらいのロジックをActiveRecordモデルに残すべきかは、どう判断すればいいのでしょうか?

スリムに。でもスリムすぎず

Active Recordは、モデルがデータベースのスキーマと密接に対応しているときに最も力を発揮するパターンです。それこそが、このパターンが設計された目的だからです。では、これは具体的にどういう意味なのでしょうか?

  • あるコードが、ActiveRecordモデルの視点から見てそのモデル自身の仕事であれば、それはモデルの中に置けます。

  • 複数のテーブルやオブジェクトにまたがる処理で、明確なオーナーが存在しない場合は、サービスオブジェクトに切り出すのがよいでしょう。

  • 属性のようなもの(アソシエーションや他の属性から計算される値など)は、ActiveRecordモデルに入れるべきです。

  • 複数のモデルの保存や更新を一度にまとめて調整するようなロジックは、ActiveModelのフォームオブジェクトに置きます。

  • ビューでの表示やフォーマットを主目的とするコードは、Railsヘルパーかプレゼンターに任せましょう。

これらのガイドラインを超えた部分については、肥大化しつつある他のクラスと同じリファクタリングの原則を適用すれば問題ありません。ただし一般的には、ActiveRecordモデルに多少のロジックを残しても罪悪感を抱く必要はありません。本来、そうあるべきものだからです。

つまり、RailsがActive Recordパターンを採用した以上、モデルにある程度のロジックを持たせるのは理にかなっています。では、Railsはなぜもっと「きれい」な設計ではなく、あえてこのパターンを選んだのでしょうか?

Rubyならどうする?

『エンタープライズアプリケーションアーキテクチャパターン(PoEAA)』において、Active Recordパターンは「ロウデータゲートウェイ」と「データマッパー」の中間に位置づけられています。ロウデータゲートウェイは、テーブルの1行を包む、ほぼ無機能なオブジェクト指向ラッパーであり、考えうる限り最もスリムなモデルと言えます。データマッパーはActive Recordよりも複雑で、ビジネスロジックのみを持つオブジェクトと、永続化ロジックのみを持つオブジェクトとの間を変換するために使われることがほとんどです。

したがって、Rubyという言語の文脈においては、Active Recordは間違いなく正しいデフォルトのパターンです。

なぜそう言えるのでしょうか?

Rubyはプログラマを幸せにするために設計された言語です。「きれいさ」と「便利さ」のトレードオフを迫られたとき、Rubyはほぼ必ず便利さを選びます。

たとえば、Arrayの公開APIには100以上のメソッドがあります。互いのエイリアスになっているメソッドも山ほどあります。.findではなく.detectと書きたい開発者がいるからです。

その文脈で考えると、Railsがより柔軟だったりオブジェクト指向的に純粋だったりするパターンではなく、便利なパターンをデフォルトに選んだのは非常に筋が通っています。それこそがRuby流です。そして私はそれが大好きです。

必要になったときに、より柔軟な構成へリファクタリングすればいいのです。とはいえ……YAGNI(今は作るな)ですけどね。

  1. DjangoでモデルデータをCSV・JSON・Excel形式にエクスポートする方法

    Djangoアプリケーションを開発していると、モデルのデータをCSV、JSON、Excel(.xlsx)などの形式でエクスポートし、レポート作成や他システムでの利用に活かしたい場面があります。自前でスクリプトを書くことでも対応できますが、実はもっと簡単な方法があります。 この記事では、「django-import-export」というパッケージを使って、Django管理画面からワンクリックでモデルデータをエクスポートする手順を解説します。 事前準備 まずDjangoプロジェクトを作成し、アプリを追加します。urls.pyの設定やINSTALLED_APPSへのアプリ登録など、基本的なセットアッ

  2. PythonのTensorFlowでシーケンシャルモデルを使うべきケースとは?具体例付きで解説

    シーケンシャルモデルが適しているのはどんなとき?シーケンシャル(Sequential)モデルは、レイヤーが単純に積み重なった「プレーンなスタック構造」を持つモデルに適しています。このスタックでは、各レイヤーが必ず1つの入力テンソルと1つの出力テンソルを持ちます。一方、以下のようなケースにはシーケンシャルモデルは不向きです。モデルに複数の入力または複数の出力がある場合複数のレイヤー間で同じレイヤーを共有する場合個々のレイヤー自体が複数の入力や出力を持つ場合非線形なアーキテクチャが必要な場合TensorFlowとKerasとはTensorFlowについてTensorFlowはGoogleが提供する