ActiveRecordパターンは、SOLID設計原則に従っていますか?


43

Ruby on Railsで有名になったActiveRecordパターンが、SOLID設計原則の使用を奨励または阻止するかどうかに興味があります。

たとえば、ActiveRecordオブジェクトには、ドメインロジックと、単一責任の違反である永続化ロジックの両方が含まれているように思えます。


6
2009年のRubyカンファレンスでの彼のSOLID Rubyトークの最後に、ジムウェイリッヒは「ActiveRecordオブジェクトはドメインコンセプトと永続性コンセプトを実装します。これはSRP(単一責任原則)に違反しますか?」視聴者は、SRPに違反することに同意します。ジムは、これが彼らを悩ませるかどうか尋ねます。聴衆の多くはイエスと言う。どうして?テストが難しくなります。永続化オブジェクトが非常に重くなります。
デビッドJ.

回答:


56

ActiveRecordには有効な批判があります。いつものように、ボブおじさん はそれを完璧に要約しています:

Active Recordの問題は、これら2つの非常に異なるスタイルのプログラミングについて混乱を招くことです。データベーステーブルはデータ構造です。データが公開されており、動作はありません。ただし、アクティブレコードはオブジェクトのように見えます。「隠された」データがあり、動作が公開されています。データは実際には隠されていないため、「隠し」という言葉を引用符で囲みます。ほとんどすべてのActiveRecord派生物は、アクセサーとミューテーターを介してデータベース列をエクスポートします。実際、Active Recordはデータ構造のように使用されることを意図しています。

一方、多くの人は、アクティブレコードクラスにビジネスルールメソッドを配置します。これにより、オブジェクトのように見えます。これはジレンマにつながります。Active Recordは実際にどちらの側に落ちますか?オブジェクトですか?それともデータ構造ですか?

ウィキペディアは、テスタビリティの懸念に関する批判をまとめています。

OOPでは、カプセル化の概念は懸念の分離の概念としばしば対立します。一般的に、懸念事項の分離を好むパターンは、孤立した単体テストに適していますが、カプセル化を好むパターンはAPIを使いやすいです。Active Recordは、データベースなしでのテストが非常に困難になる点まで、カプセル化を大いに支持しています。

具体的には、Ruby on Railsの実装について、Gavin Kingは次のように書いています(私の強調)

この時点で、ほとんどの開発者はうーん、そうだと思っているので、コードを見て会社がどのような属性を持っているかをどうやって知るのでしょうか?そして、私のIDEはそれらをどのように自動補完できますか?もちろん、Railsの人たちはこの質問にすばやく答えています。ああ、データベースクライアントを起動して、データベースを調べてください!その後、ActiveRecordの自動大文字と複数形のルールを完全に知っいると仮定すると、独自のCompanyクラスの属性の名前を推測し、それらを手動で入力できます。

また、Ruby on Railsの実装について、John Januszczak氏は次のように書いています(強調鉱山)。

問題#1:静的メソッド

...

静的メソッドの使用は手続き型プログラミングに過ぎないため、オブジェクト指向の設計が不十分であると言う人もいます。他の人は、静的メソッドはテスト可能性の死であると言うでしょう。

問題#2:グローバル構成設定

...

したがって、この例のAccountクラス、および拡張によるAccountインスタンスへの依存性注入はありません。今までに知っておくべきことですが、物を探すのは非常に悪いです!

ActiveRecordとORMが一般にアンチパターンであると考えられる理由に関するいくつかのリソース:

ActiveRecordは常に非常に有用なアンチパターンのように感じましたが、SRPに反すること、さらに依存関係の反転の原則に反することにも同意します。


rails 5+の重要な更新:「そして、どうすればIDEでそれらを自動補完できますか?もちろん、Railsの人々はこの質問にすばやく答えています。もう。属性のAPIを使用すると、モデルで利用可能なすべての列を定義することができます
フィリップBartuzi

6

(ActiveRecordクラスは依存性注入の可能性なしに実装されていると仮定しています)。

個人的な経験から言えば、ActiveRecordパターンは単体テストを書く上で大きな障害になると言えます。永続層とビジネスロジックを1つの「ActiveRecordクラス」に結合すると、ユニットテストを書くことができなくなります(最初にリファクタリングしない限り)。したがって、唯一のオプションは統合テストの作成です。それは単体テストほど効果的ではありません。これは、特に多数のActiveRecordクラスを持つプロジェクトを引き継ぐ場合に大きな問題になります。維持が困難な非常に複雑な統合テストになります。

そのため、ActiveRecordはSRPにほとんど反しており、メンテナンスの頭痛の種です。単体テストを書く力を奪っているようです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.