9

ここで無知を許してください。私はDDDにかなり慣れていないので、優しくしてください。

私は大規模な構成駆動のデータ管理システムに取り組んでいます。システムは、構成の一部 (ビジネス ルール、プロセス、検証など) を外部構文で指定することによって構築されます。構文は、Groovy ベースの DSL と Drools の集合体であるとだけ言っておきましょう。

私は、DDD が提供するシンプルさのアイデアが好きです。具体的には、ドメインのコア コンセプトからインフラストラクチャの問題を分離しています。

ただし、システムの構成可能な性質のために、DDD の概念のいくつかを適用するのに苦労しています。動作 (プロセス)、検証、およびビジネス ルールの両方が、システムの外部で定義されます。したがって、ドメイン内のエンティティは本質的に独自の動作を持ちません。むしろ、彼らは「バリデーター」や「ルールエンジン」、「ワークフローエンジン」に細心の注意を払っています。

例を挙げて説明します。私のシステムが会社の従業員を管理しているとしましょう。あまり深く考えなくても、私のドメインには Employee エンティティと Company エンティティがあると想像できるでしょう。

DDD に続いて、従業員が昇進するシナリオをモデル化しようとしています。従業員に対しては、promote (Employee.promote) という新しいメソッドが作成されることがあります。従業員が同じ年に 2 回昇進できないことを示すビジネス ルールを作成できます (はい、これはすべてでっち上げです)。したがって、次のようなものがあります。

public void promote( EmployeeLevel newLevel ) {
  if ( hasBeenPromotedThisYear( this ) {
    throw new InvalidPromotionException

さて、私が使用しているアプリケーションでは、このビジネス ルールはルール エンジンに外部化されます。DDDに続いて、次のようなことができます:

if( promotionRules.isEligibleForPromotion(this)

私のルールを外部化する。ただし、システムはこれよりもはるかに一般的です。「プロモーション」操作自体は、外部構成によって「プロセス」として定義されます。したがって、コンパイル時には、この従業員に「昇格」操作を使用できるかどうかさえわかりません。したがって、私の従業員オブジェクトは、コードの観点からはかなりむき出しになり、すべての機能が構成に委譲されます。次のようになります。

public class Employee {
  public void execute( Process process )

または代わりに

public class EmployeeProcess {
  public void process( Employee employee )

私の質問は、DDD はこのアプリケーションでも意味があるのでしょうか? 代わりに、DDD 以外の意味で、プロセス、検証、ビジネス ルール (ルール エンジン) のコラボレーションをモデル化する必要がありますか?

私は Onion Architecture が好きで、UI -> App Services -> Core -> Infrastructure を使用して、問題を適切に分離することができます。しかし、コアは、実際の「ドメイン概念」とは対照的に、上記の協力者である可能性があります。

この場合、「ドメインの概念」はバリデーター、プロセッサー、ビジネス ルールであると、私の一部は信じています。この場合、(ほとんどの場合) 実際の動作を持たないエンティティと、システム内の動作を実現するプロセッサ、バリデーター、ルール エンジンに関するドメイン コンセプトを使用します。

もう少し情報を追加します。上記の私の質問を踏まえて、私は次のような解決策に取り組んでいました。

org.example.app

org.example.domain - 従業員 - 会社 - 従業員レベル

org.example.domain.shared - プロセス - ビジネスルール - バリデーター

org.example.infrastructure

うまくいけば、この小さなスニペットが少し明確になります。

したがって、Process、BusinessRule、および Validator の概念はドメイン内にありますが、システムが行うことに関してドメイン モデルをサポートします。

4

2 に答える 2

2

ウィキペディアから:

ドメイン駆動設計 (DDD) は、コア ビジネス コンセプトの進化するモデルに実装を深く結び付けることによって、複雑なニーズに対応するソフトウェアを開発するアプローチです。

バリデーター、プロセス、ルールはビジネスのコア概念ではないと思います。これらはかなり一般的なソフトウェアの抽象化です。

私は「書籍による」DDD の大ファンではありませんが、より「ドメイン駆動型」にするためには、DSL とルールを実際にビジネスの概念に基づいて構築し、より意味のあるものにする必要があります。

内部では、バリデーター、プロセス、マネージャー、エグゼキューターなどを引き続き使用できますが、ソフトウェアの抽象化ではなく、ビジネスの概念を使用すると、DSL/ルールが読みやすくなります。

UPDATED : DSL の定義に Groovy を使用しているため、Groovy の動的メソッド名解決とビルダー機能を使用して、読み取り可能なルールとクラスを作成できます。また、「設定より規約」の原則を利用して、いくつかのロジックをフックすることもできます。たとえば、Groovy では、次のようなものを構築しようとすることができます。

if (employee is "promotable") {
  start "promotion" for employee
}

isたとえば、EmployeePromotableValidator クラスの存在をチェックするベース ドメイン オブジェクトのメソッドになります。このクラスは、それ自体が Groovy の DSL 表現力を活用する Groovy クラスになることもあります。

class EmployeePromotableValidator extends Validator<Employee> {

  boolean validate(Employee employee) {
    employee.age > 25 && employee.workingYears > 2
  }

}

startクラスを検索するベースルールスクリプトのメソッドになりますEmployeePromotionProcess。これもGroovyクラスにすることができます。

この場合の仕様パターンは、基本的に言語の一部になるため、非常に単純です。

if (employee is "promotable" && 
    employee is "advanced" && 
    employee.salary < 10000) {
  start( "salary increase", "10%" ) for employee
}

一般に、Groovy/Scala などの (半) 関数型言語を使用した DSL を使用して、ソフトウェアの抽象化を隠し、ビジネス ロジックをコード内でより目立たせることができます。プレーンな Java を使用すると、多くのボイラー プレート コードが作成され、最終的にすべての意図が隠されます。

于 2012-09-12T08:18:39.023 に答える
1

それはあなたのビジネスドメインが正確に何であるかに依存します。

何かコンストラクターがすべてのアプリケーションを実行する、大きな追加の構成可能なcrmを構築している場合、ビジネスドメインはそれを可能にしているためProcessExecutorsなどの名詞はドメインの一部です。

従業員とその昇進性に関する情報を追跡する必要があるアプリケーションを構築している場合、ビジネスドメインはすべて、従業員、給与、パフォーマンス測定に関するものです。この場合、、および同様のオブジェクトをドメインへの侵入者として扱いProcessますExecutors

あるレベルでは、プログラミング言語自体でさえ、頭の中で描いている問題の解決策を曖昧にする侵襲的なツールです。しかし、それは必要なものです-そうでなければ、それを実現することはできません。

于 2012-09-13T13:12:31.517 に答える