2012-05-04 7 views
15

An interesting thread私はこの質問にちょうど今入力しました。私はそれが私の質問に答えるとは思わない。"リッチドメインモデル"は単一責任原則に違反する可能性がありますか?

私は、貧血モデルを持つことが望ましい.NET MVC3で多くの作業をしてきました。ビューモデルと編集モデルは、コントローラからビューに渡すだけのダムデータコンテナとして最適です。あらゆる種類のアプリケーションフローがコントローラから来て、ビューがUIの問題を処理します。 MVCでは、モデル内で動作する必要はありません。

しかし、コントローラにはビジネスロジックも必要ありません。より大きなアプリケーションの場合、ドメインコードをモデル、ビュー、およびコントローラ(およびその点で一般にHTTP)から分離して独立させることが最善です。したがって、ドメインモデル(エンティティと値オブジェクトを持つ、DDDに従って集計されたもの)を他に先んじて提供する別個のプロジェクトがあります。

私はドメインコードで貧血モデルからより豊かなものへと移行しようとしましたが、私はあきらめて考えています。私は、データと動作を含むエンティティクラスがSRPに違反しているように思えます。

たとえば、メールを作成してウェブ上で非常に一般的なシナリオを1つ実行します。いくつかのイベントがある場合、EmailTemplate、EmailAddress、およびカスタム値を指定してEmailMessageオブジェクトを作成するのは、ドメインの責任です。テンプレートはプロパティを持つエンティティとして存在し、カスタム値はユーザーによって入力として提供されます。また、EmailMessageのFROMアドレスが外部サービス(IConfigurationManager.DefaultFromMailAddress)によって提供されるという議論のために、

public class EmailTemplate 
{ 
    public EmailMessage ComposeMessageTo(EmailAddress to, 
     IDictionary<string, string> customValues, IConfigurationManager config) 
    { 
     var emailMessage = new EmailMessage(); // internal constructor 
              // extension method 
     emailMessage.Body = this.BodyFormat.ApplyCustomValues(customValues); 
     emailMessage.From = this.From ?? config.DefaultFromMailAddress; 
     // bla bla bla 
     return emailMessage; 
    } 
} 

これは、豊富なドメインモデルでの私の試みの一つであった。これらの要件を考えると、豊富なドメインモデルがEmailTemplateにEmailMessageのを構成する責任を与えることができるように思えます。このメソッドを追加した後、エンティティデータプロパティを格納してメッセージを作成するのはEmailTemplateの責任でした。それは約15行の長さで、クラスを実際にEmailTemplateになるように散らばっているように見えました。IMOは、データ(件名フォーマット、本文フォーマット、添付ファイル、オプションの/返信先アドレス)。

私はこのメソッドを専用のクラスにリファクタリングしてしまいました。このクラスでは、以前の議論でEmailMessageを作成することに専念しています。実際には、私は貧血の領域を好むようになり始めています。なぜなら、責任と責任を別々にして、クラスや単体テストを短く、簡潔に、より集中的にするためです。エンティティやその他のデータオブジェクトを「行動がない」ものにすることは、責任を分けるうえで良いことになると思われます。または私はここでトラックをオフですか?

+1

リッチドメインモデルは、関連性の高い文脈のためだけに豊富である必要があります。 –

答えて

19

貧血モデルではなくリッチドメインモデルを支持する議論は、行動とデータを隣り合わせに保つOOPの価値命題の1つに左右されます。コアの利点は、コードについての推論を支援するカプセル化と結合の利点です。リッチドメインモデルは、information expertパターンのインスタンスとして見ることもできます。しかし、これらすべてのパターンの価値は大部分が主観的です。データと行動を別々に保つことがより有益な場合は、そのようにしてください。ただし、コードを見ている他の人も考慮する必要があります。私は可能な限りカプセル化する方が好きです。この場合、より豊かなドメインモデルのもう1つの利点は、特定のプロパティをプライベートにする可能性にあります。プロパティがクラスの1つのメソッドでのみ使用されている場合、そのプロパティを公開するのはなぜですか?

リッチドメインモデルがSRPに違反するかどうかは、責任の定義によって異なります。 SRPによれば、責任は変更の理由であり、それ自体が定義を必要とします。この定義は、一般的に手元のユースケースに依存します。テンプレートクラスの責任はテンプレートであることを宣言することができます。その意味のすべては、テンプレートからメッセージを生成しています。テンプレートのプロパティの1つが変更されると、ComposeMessageToメソッドに影響を与える可能性があります。これはおそらく単一の責任であることを示しています。さらに、ComposeMessageToメソッドがテンプレートの中で最も興味深い部分です。テンプレートのクライアントは、メソッドがどのように実装されているか、またはテンプレートクラスのどのプロパティが存在するかは気にしません。テンプレートに基づいてメッセージを生成するだけです。これは、メソッドの横にデータを保持することにも有利です。

+0

優秀な回答、ありがとうございます。 – danludwig

0

これは、あなたがどのように見たいかによって異なります。

もう1つの方法は次のとおりです。"1つの責任原則がリッチドメインモデルに違反することはありますか?"

どちらもガイドラインです。ソフトウェア設計のどこにでも「原則」はありません。しかし、良いデザインと悪いデザインがあります。これらのコンセプトはどちらも、さまざまな方法で使用でき、優れたデザインを実現します。

関連する問題