web-dev-qa-db-ja.com

プロジェクト構造:ビジネスロジックを配置する場所

まず第一に、私はビジネスロジックがどこに属しているかを尋ねているのではありません。これは以前に尋ねられたことがあり、私が読んだほとんどの回答はモデルに属していることに同意しています:

MVCデザインにビジネスロジックを配置する場所
コントローラーレイヤーに存在できるビジネスロジックの量はどれくらいですか?
「ビジネスロジックはモデルではなくサービス内にある必要があります」はどの程度正確ですか?
ビジネスロジックをモデルに組み込む理由。複数のタイプのストレージがあるとどうなりますか?

ただし、このロジックをクラス間で分散する方法については意見が分かれています。思考には3つの主要な流れが存在するようです。

  1. 内部にビジネスロジックを持つファットモデル エンティティ クラス。
  2. 「サービス」クラスの貧血モデルとビジネスロジック。
  3. 場合によります。

私はそれらすべてに問題があると思います。

最初のオプションは、ほとんどのFowleritesが固執するものです。ファットモデルの問題は、ビジネスロジック機能がクラスに関連するだけでなく、代わりに他の多くのクラスを使用することです。たとえば、Webストアを開発している場合、注文の合計を計算する関数が必要です。この関数をOrderクラス内に配置することを考えることができますが、実際に何が起こるかというと、ロジックは別のクラスを使用する必要があるということです。Orderクラスに含まれるデータだけでなく、Userクラス、Sessionクラス、そしておそらくTaxクラス、カントリークラス、ギフトカード、支払いなど。これらのクラスのいくつかはOrderクラス内で構成できますが、他のクラスは構成できません。例があまりよくない場合は申し訳ありませんが、私が何を言っているのか理解していただければ幸いです。そのような関数をOrderクラス内に配置すると、単一責任の原則が破られ、不要な依存関係が追加されます。ビジネスロジックはエンティティクラス全体に散在しているため、見つけにくくなっています。

2番目のオプションは通常私が従うものですが、多くのプロジェクトの後で、ビジネスロジックを保持する1つまたは複数のクラスに名前を付ける方法についてはまだ疑問があります。私の会社では通常、オフライン機能を備えたアプリを開発しています。ユーザーはトランザクション全体をオフラインで実行できるため、すべての検証ルールとビジネスルールをクライアントに実装する必要があり、通常はサーバーと同期するバックグラウンドスレッドがあります。したがって、通常、すべてのプロジェクトに次のクラス/パッケージがあります。

  • データモデル(DTO)
  • データアクセス層(持続性)
  • Webサービスレイヤー(通常、WSごとに1つのクラス、およびWSメソッドごとに1つのメソッド)。

ここで、ビジネスロジックの標準的なアプローチは何ですか?すべてのロジックを保持する単一のクラス?複数のクラス? (もしそうなら、それらの間でロジックを分散するためにどのような基準が使用されますか?)そして、どのようにそれらに名前を付けるべきですか? FooManager? FooService? (私は最後のものが一般的であることを知っていますが、私たちの場合、WSレイヤーには通常FooWebServiceという名前のクラスがあるので、それは悪い名前です)。

3番目のオプションはおそらく正しいものですが、有用な情報も含まれていません。

総括する:

  • 最初のアプローチは好きではありませんが、その禅を完全に理解できなかった可能性があることは認めます。したがって、脂肪モデルを唯一かつ普遍的な解決策として支持する場合は、正しい方法を説明するリンクを投稿してください。
  • OO言語での2番目のアプローチの標準設計と命名規則は何ですか?特にクラス名とパッケージ構造です。次を含めることもできます。それがどのように行われるかを示すオープンソースプロジェクトへのリンク。

前もって感謝します。

5
Mister Smith

私はあなたがファウラーを誤解したと思います、彼は1ではなく3を主張しています( http://www.martinfowler.com/bliki/AnemicDomainModel.html を参照してください)。彼は「エンティティー・クラス内のビジネス・ロジック」について話しているのではなく、「domainクラス内のビジネス・ロジック」について話していることに注意してください。また、サービスオブジェクトドメインオブジェクトです。

上記の例:注文合計を計算する必要がある場合は、サービスクラス「OrderTotalCalculator」を作成してみませんか?目的に応じてクラスに名前を付けます(実際に目的を隠すOrderServiceやOrderManagerではありません)。

そのようなサービスクラスを導入するタイミング、およびビジネスロジックがエンティティ内に留まる可能性がある場合の基準については、すでに1つの基準について述べています。 。また、単一責任の原則についても触れたので、これを参考にしてください。

ただし、これは必ずしもオプション2につながるとは限りません-私の経験では、ごとに追加のサービスクラスを導入しなくても、エンティティが完全な責任を負うことができる十分なビジネスオペレーションが通常あります操作。これは通常、lean(貧血ではない)エンティティークラスにつながります。

3番目のオプションはおそらく正しいものですが、有用な情報も含まれていません。

はい、おそらくそれは正しいものですが、「有用な情報がない」とはどういう意味ですか?これの取扱説明書を見逃していますか?ソフトウェア開発は、組立ラインでの作業とは異なり、設計プロセスです。したがって、正しい設計決定を行うのは必ずしも容易ではなく、多くの経験が必要です。そして、物事に名前を付けることは 実際には最も難しいタスクの1つ です。

6
Doc Brown