厚いモデルと ビジネスロジック、どこから区別を引きますか?


16

今日、私は組織の別の開発者とデータベースマップクラスにメソッドを追加する場所と方法について、激しい議論になりました。を使用しsqlalchemy、データベースモデルの既存のコードベースの大部分は、クラス名を持つマッピングされたプロパティのバッグ、データベーステーブルからpythonオブジェクトへのほぼ機械的な変換に過ぎません。

議論の中で、私の立場は、ORMを使用する主な価値は、マップされたクラスに低レベルの動作とアルゴリズムを付加できることだということでした。モデルは最初にクラスであり、2番目に永続的です(ファイルシステムでxmlを使用して永続的である可能性があるため、気にする必要はありません)。彼の見解では、すべての動作は「ビジネスロジック」であり、必然的に、データベースの永続化のみに使用される永続モデル以外のどこかに属します。

私は確かにビジネスロジックと区別されていると思いますが、それは実装方法の下位レベルからある程度分離されているので、分離する必要があります前の段落で議論しましたが、私はそれが何であるかについて指を置くのに苦労しています。私は、彼らがしたいとのAPI呼び出しているユーザーには、(我々の場合には、HTTP「安らか」である、)APIが何であるかのより良い感覚を持っていません、彼らが行うことを許可されているものとは異なった、そしてどのように完了します。


tl; dr:ORMを使用する場合、マップされたクラスのメソッドにはどのような種類の要素を含めることができますか?


同時に議論された2つの問題であるように思えます、永続モデルの問題は最初にクラスであり、2番目に永続的です(ファイルシステムでxmlを使用して永続的である可能性があり、気にする必要はありません)。およびコードの理由。通常、少なくとも私にとっては、コードがなぜ書かれているの、どのような要件がこのコードを強制するのを自問すると、事態は明らかになります。それは、プログラムがどのように機能するに関する顧客の要求ですか、それとも私たちがどの方法でそれを実装することを選択するかです。私にとって最初はビジネスロジックであり、2番目はドメインロジックと呼ばれるものです。これがどのように役立つか。

回答:


10

私はほとんどあなたと一緒です。あなたの同僚は、貧弱なドメインモデルのアンチパターンまたは明白な利点のない「永続性モデル」でのモデルの複製のいずれかを主張しているようです(これが行われたJavaプロジェクトに取り組んでいます。モデルで何かが変更されるたびに3倍の作業を意味します)。

ORMを使用する場合、マップされたクラスのメソッドにはどのような種類のものを入れることができますか?

経験則:クラスには、すべての状況下で当てはまるデータに関する基本的な事実を記述するロジックを含める必要があります。ユースケースに固有のロジックは別の場所にある必要があります。例は検証です。MartinFowler からの興味深い記事があり、コンテキスト依存と見なされるべきであると主張しています。


+1、回答の2番目の部分。最初の部分については、なぜ貧血ドメインモデルが変更の場合に多くの「余分な」作業を必要とするのか、あなたが言う理由は確かです。私の理解では、変更はいくつかの異なるクラスで発生しますが(これは一種の悪いことですが)、ほぼ同じ量の変更です。私は推測する?
-NoChance

1
@Emmad Kareem:コメントは、スピアートの永続性とドメインモデルを持つことについてでした。モデルにプロパティを追加するには、2つのモデルクラス(1つではなく)とそれらの間のマップ(理論上は自動ですが、通常は別のモデルクラスを作成することをお勧めします)に追加する必要があります「持続性モデル」は、それらを異なるものにすることによってその分離を正当化することを決定します。たとえば、DBタイプモデルにより厳密に一致するデータ型を持つようにします。マッピングの問題。
マイケル・ボルグワード

3

これは、あなたが開発しているものの予想されるサイズと規模に本当に依存する判断の呼び出しです。最も厳格なアプローチは、ORMタイプをデータアクセスコンポーネントに制限し、すべてのレイヤーで参照および使用されるタイプとして共通ライブラリ内のPOCOを使用することです。これにより、将来の物理的な分離と論理的な分離が可能になります。UIとビジネスロジックレイヤーの間に追加のレイヤーが存在することを決定することもできます。これは通常、ファサードまたはビジネスインターフェイスレイヤーと呼ばれます。この追加の層は、「ユースケースコード」が存在する場所です。個々の疎結合コードは、Facade / BIレイヤーによって呼び出されます(たとえば、Facadeには、ビジネスロジックを1:M回呼び出して実際に注文を処理するために必要なすべてのステップを実行するProcessOrder()関数があります)。

ただし、そのすべてが言われています。多くの場合、この量の設計は単純に不必要なやり過ぎです。たとえば、コンポーネントを再利用のためにパッケージ化する意図がない単純なWebサイト専用のコード。MVC Webサイトを作成し、このタイプのソリューションにEFオブジェクトを使用することは完全に有効です。サイトを後でスケールアウトする必要がある場合は、クラスタリングまたは「リファクタリング」と呼ばれるプロセスが失われることがよくあります。


3

同僚に、これがJavaプロジェクトであるかのようにモデルをオーバーアーキテクチャ化する必要がないことを思い出してください。つまり、2つの永続化されたオブジェクトを比較することは動作ですが、永続化レイヤーによって指定されるものではありません。6ビールの質問は次のとおりです。なぜ同じことについて完全に無関係なクラスが何かを記述しているのでしょうか。確かに、永続性は、モデルを個別に扱うには十分な大きな側面ですが、他のすべてと区別して扱うことを保証するには十分ではありません。車を運転したり、洗ったりバストしたりすると、ずっと車を操作します。

それでは、これらすべての異なる側面を単一のモデルクラスにまとめてみませんか?永続化されたオブジェクトを扱う一連のクラスメソッドが必要です。1つのクラスに入れてください。検証を処理する多数のインスタンスメソッドがあり、それらを別のインスタンスメソッドに配置します。最後に、2つを混ぜ合わせて出来上がり!スマートで自己認識があり、完全に含まれるモデル表現がすぐに得られました。


1

他の回答に加えて、ORMでリッチドメインモデルを使用する場合は、隠れた洞窟に注意してください。

次の擬似コードのようなものを達成しようとすると、永続化されたモデルクラスにポリモーフィックサービスを注入する際に問題が発生しました。

Person john = new Person('John Doe')
Organisation company = organisation_repository.find('some id')
Employee our_collegue_john = company.hire(john)

この場合、組織は HRService(たとえば)コンストラクターの依存関係をます。通常、ORMを使用する場合、モデルクラスのインスタンス化を簡単に制御することはできません。

私はDoctrine ORMとSymfonyのサービスコンテナを使用していました。私はORMをそれほどエレガントではない方法でパッチ適用しなければならず、永続性モデルとビジネスモデルを分離するしかありませんでした。私はまだsqlachemyで試したことがないと思った。このような場合、PythonはPHPよりも柔軟であることが判明する可能性があります。

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