web-dev-qa-db-ja.com

ActiveRecordパターンはSOLID設計原則に準拠/奨励していますか?

Ruby on Railsで有名になっている)ActiveRecordパターンが [〜#〜] solid [〜#〜] デザインの使用を奨励または推奨していないかどうかに興味があります原則。

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

43
nicholaides

ActiveRecordにはいくつかの正当な批判があります。いつものように、 ボブおじさん完全に合計します

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

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

ウィキペディアは批判を テスト容易性の懸念 で要約しています:

OOPでは、カプセル化の概念は関心事の分離の概念と矛盾することがよくあります。一般的に、関心事の分離を支持するパターンは分離された単体テストに適していますが、カプセル化を支持するパターンはより簡単です。 APIを使用するために、Active Recordは、データベースなしでのテストが非常に困難になるまで、カプセル化を強く支持しています。

特にRuby on Rails実装、 Gavin Kingが書いている (私の強調)):

この時点で、ほとんどの開発者はうーん、わかりました。コードを見て、会社がどのような属性を持っているのかを知るにはどうすればよいでしょうか。 IDEそれらをオートコンプリートするにはどうすればよいですか?もちろん、Rails人々はこの質問にすばやく回答します。ああ、データベースクライアントを起動して、データベースを調べてください!次に、assumingで、ActiveRecordのオートマジック大文字化と複数化の規則がわかっていることを確認します/perfectly/、自分のCompanyクラスの属性の名前を推測して、手動で入力できるようになります。

Ruby on Rails implementation、 John Januszczak writes (鉱山強調):

問題#1:静的メソッド

...

静的メソッドの使用は手続き型プログラミングに相当するため、オブジェクト指向の設計としては不十分だと言う人もいます。他の人は、静的メソッドはテスト容易性にとって死ぬと言います。

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

...

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

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

ActiveRecordは常に非常に便利なアンチパターンのように感じましたが、SRPおよび依存関係の逆転の原則に反することに同意します。

56
yannis

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

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

そのため、ActiveRecordはSRPにかなり対抗し、いくつかのメンテナンスの頭痛を引き起こします。ユニットテストを書く力を奪うようです。

6
Guven