7


4

Rails ActiveRecordをハイブリッド構造として使用していますか? データ構造+オブジェクト?

私は4年以上Railsを使用してきましたが、明らかにRailsが好きで、Rails Wayで物事をするのが好きです。

私は最近、ボブおじさんによるクリーンコードを取り上げました。 私は第6章にいますが、私たちがレール開発者としてオブジェクト指向設計の非常に基本的なルールを破っているかどうか、少し混乱しています。 デメテルの法則またはカプセル化? デメテルの法則では、オブジェクトは別のオブジェクトの内部を認識してはならず、メソッドによって返されるオブジェクトのメソッドを呼び出すべきではないと述べています。

しかし、多くの場合、モデルから別のオブジェクトのメソッドを呼び出します。 たとえば、「注文はユーザーに属している」などの関係がある場合です。 その後、非常に頻繁にorder.user.nameを実行するか、または列車の大破のように見えないようにするために、order.nameを実行するようにデリゲートを設定します。

  1. それはまだデメテルの法則やカプセル化を破るようなものではありませんか?

  2. もう1つの質問は、ActiveRecordが単なるデータ構造またはデータであるかどうかです。 データベースと連動するオブジェクトを転送しますか?

  3. はいの場合、ハイブリッド構造を作成しないでください。 半分のオブジェクトと ActiveRecordモデルにビジネスルールを入れることでデータ構造が半分になりますか?

4 Answer


15


RailsはRailsです。 他に何と言っていますか。 はい、Railsのいくつかのイディオムは優れた設計原則に違反しています。 しかし、Railsの方法であるため、これを許容します。

とはいえ、ほとんどのレールアプリケーションではモデルの使用が多すぎます。 あまりにも頻繁に、モデルに直接アクセスするビューコードが表示されます。 アクティブなレコードオブジェクトにビジネスルールが組み込まれています。 より良い方法は、アクティブなレコードからビジネスルールを分離し、モデルからビューを分離することです。 これはRailsのイディオムに違反することはなく、Railsアプリケーションの柔軟性と保守性が大幅に向上します。


7


私見では、純粋主義的なアプローチをやりすぎると、Javaのような混乱に陥り、正しいデザインパターンをすべて使用しますが、ファイルを開いてその内容を読むために必要な8行のコードを覚えている人は誰もいません。

RailsのActiveRecordフレームワークは、Martin Fowlerのhttp://en.wikipedia.org/wiki/Active_record[Active Record design pattern]の実装です。 RailsのActive Recordは、ふるまいを持っているため、確かに単純なデータ構造やDTOだけではありません。検証を実行し、属性が変更されたかどうかを通知できます。 そしてあなたは自由であり、実際にhttp://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model[encouraged]で、そこに独自のビジネスロジックを追加します。

Railsは一般に、優れた実践を奨励しています。 MVCと構文ビネガーを使用して、悪いことを難しくしたり、見苦しくしたりします。


4


はい、ActiveRecordは意図的にカプセル化を解除します。 これは、Railsのベースとなるパターンの制限であるため、Railsの制限ではありません。 ActiveRecordの定義がRailsで使用されているテンプレートであるMartin Fowlerは、https://rads.stackoverflow.com/amzn/click/com/0321127420 [POEAA]のActiveRecordの章で次のように述べています。

_ _Active Record_に対するもう1つの論点は、オブジェクト設計をデータベース設計に結合しているという事実です。 これにより、プロジェクトの進行に合わせて、いずれかの設計をリファクタリングすることがより困難になります。 _

これは、他のフレームワークからのRailsのhttp://www.web4j.com/Criticisms_Drawbacks_Pitfalls_Spring_Rails_PHP.jsp [よくある批判]です。 Fowler自身はActiveRecordが主に使用されると言っています

_ …​for domain logic that isn’t too complex…​if your business logic is 複雑な場合は、すぐにオブジェクトの直接の関係、コレクション、継承などを使用する必要があります。 これらはActive Recordに簡単にマッピングできません。 _

ファウラーはさらに、複雑なドメインロジックを使用するより深刻なアプリケーションの場合、http://martinfowler.com/eaaCatalog/dataMapper.html [データマッパーパターン]が望ましいと述べています。 これは、Rails Merbへの今後の動きが一般的に前向きな動きと見なされている理由の1つです。 Rails、MerbはActiveRecordに加えてDataMapperパターンを使用します。

DemeterがActiveRecordの主な関心事であるかどうかはわかりません。 むしろ、データ層とドメイン層の間のカプセル化を破ると、ボブおじさんのhttp://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod [単一責任原則]が壊れると思います。 デメテルは、オープン/クローズド原則に従う方法のより具体的な例だと思います。 しかし、これらすべての背後にあるより広い考え方は同じだと思います:クラスは1つのことを行い、将来の変更に対して堅牢でなければなりませんが、ある程度ActiveRecordはそうではありません。


1


「デメテルの法則」に関して、私が言及したことのないものの1つは、距離の概念です。 つまり、「オブジェクトはどの程度密接に関連していますか?」という意味です。私が「デメテルの法則」に従うことを気にするかどうかにかかわらず、これはいくらかの違いを生むだろうという私の意見です。

ActiveRecordの場合、LoD違反のほとんどに関与するオブジェクトは密接な関係に不可分に結合されます。 これらのオブジェクトの内部データ構造を変更するには、その新しい構造を反映するためにデータベースを変更する必要があります。 通常、データベースのテーブルは単一のデータベースに「バインド」され、外部キー制約(または少なくとも主キーと外部キーを含む)を通じてこれらの「関連付け」を反映します。

したがって、一般的に、ARオブジェクト間でLoDを追跡することに関心はありません。 私は彼らがまさにその性質のために互いに密接に結びついていることを知っています。

一方、私はより遠くのオブジェクト、特にMVCの境界を越えるオブジェクトや他のそのような設計デバイスの間のLoDをより懸念します。