エンティティの単一の責任(変更する理由)は、それ自体を一意に識別することである必要があります。言い換えると、その責任を見つけられるようにすることです。
エリックエヴァンのDDDの本、ページ。93:
エンティティの最も基本的な責任は、動作が明確で予測可能なように継続性を確立することです。彼らは予備にされている場合、彼らはこれを最善にします。属性や動作に焦点を当てるのではなく、Entityオブジェクトの定義を最も本質的な特性、特にそれを識別する、またはそれを検索または一致させるために一般的に使用される特性まで取り除きます。その動作に必要な概念と属性に不可欠な動作のみを追加します。
それを超えて、コアエンティティに関連付けられた他のオブジェクトへの動作と属性を削除することを検討してください。
1。
... ENTITYオブジェクトの定義を最も本質的な特性、特にそれを識別する、またはそれを検索または一致させるために一般的に使用される特性まで取り除きます。コンセプトに不可欠な動作のみを追加します...
いったんエンティティが割り当てられている固有のIDを、そのアイデンティティが確立され、私はそのような実体がするいかなる行動を必要としないと仮定しますので、そのアイデンティティを維持したりするために、それは自分自身を識別するのに役立ちます。したがって、著者が「概念に不可欠な振る舞い」find
とはどのような振る舞いを参照しているのか理解できません(およびmatch
操作以外)。
2。
... ENTITYオブジェクトの定義を最も本質的な特性、特にそれを識別する、またはそれを検索または一致させるために一般的に使用される特性まで取り除きます。...さらに、動作と属性を削除して、コアENTITYに関連付けられている他のオブジェクトを探します。
そのため、エンティティを特定するのに役立たないが、そのエンティティの固有の特性として行動を特徴付けます(つまり、characterえは犬に固有、飛行は飛行機に固有、産卵は鳥に固有です。) 。)、そのエンティティに関連付けられている他のオブジェクトに配置する必要があります(例:犬のエンティティに関連付けられているオブジェクトにbarえる動作を配置する必要があります)?
3。
それを超えて、コアENTITYに関連付けられた他のオブジェクトの動作と属性を削除してください。
a)MyEntity
責任A_resp
をおよびにそれぞれ委任B_resp
します。a
b
ほとんどのにもかかわらずA_resp
とB_resp
仕事をすることによって行われa
、およびb
インスタンス、クライアントはまだ提供されているA_resp
とB_resp
通じMyEntity
クライアントの観点から二つの責任はに属していることを意味しています、MyEntity
。したがって、それはMyEntity
またA_resp
、B_resp
責任と責任を持っていることを意味していないので、SRPに違反していますか?
B)私たちがいることを前提としていてもA_resp
とB_resp
に属していないMyEntity
、MyEntity
まだ責任があるAB_resp
オブジェクトの動作を調整するにa
してb
。そうしないMyEntity
違反SRPを最低でも、それは持っているので、2つの責任を一意に自身を識別し、またして- AB_resp
?
class MyEntity
{
private A a = ...
private B b = ...
public A GetA()
{ ... }
public B GetB()
{ ... }
/* coordinates operations of objects a and b */
public int AworkB()
{ ... }
}
/* A encapsulates a single responsibility resp_A*/
/* A is value object */
class A
{ ... }
/* B encapsulates a single responsibility resp_B*/
/* B is value object */
class B
{ ... }
更新:
1。
このコンテキストでの動作は、セマンティック動作を指します。たとえば、クラスのプロパティ(つまり、ドメインオブジェクトの属性)を一意に識別するために使用されるプロパティには、動作があります。これはコードでは直接表されませんが。予想される動作では、そのプロパティに重複する値はありません。
そのため、コードでは、エンティティのIDを何らかの形で維持する動作(つまり、操作)を実際に実装する必要はほとんどありません。そのような動作は、ドメインモデルの概念として(IDエンティティ)、ただし、このID属性をコードに変換すると、そのセマンティクスの一部が失われます(つまり、ID値が一意であることを暗黙的に確認する部分が失われます)?
2。
さらに、AgeなどのプロパティはPersonエンティティの外部にコンテキストを持たないため、別のオブジェクトに移動しても意味がありません...しかし、その情報は一意の識別子、つまり動作への混乱した参照。年齢は、遅延読み込み値である可能性があります。
a)Age
プロパティが遅延ロードされる場合、意味論的Age
に単なる属性であるにもかかわらず、ビヘイビアと呼ぶことができますか?
3。
有効な住所であることの確認など、住所固有の操作を簡単に行うことができます。設計時にはそれを知らないかもしれませんが、このコンセプト全体はオブジェクトを最小の部分に分解することです
Age
別のオブジェクトに移動するとコンテキストが失われることに同意しますが、DateOfBirth
プロパティを別のオブジェクトに移動してもコンテキストは失われませんが、通常は移動しません。
Address
別のオブジェクトに移動する主な理由は何DateOfBirth
ですか?エンティティにDateOfBirth
本質的であるため、Person
または将来どこかに特定の操作を定義する必要がある可能性が低いためDateOfBirth
です。
4.私は、私はまだかどうかわからないと言わなければならないMyEntity
もありA_resp
とB_resp
責任と理由MyEntity
もあるが、AB_resp
違反とはみなされませんSRP
EULERFX
1)
著者が参照している動作は、エンティティに関連付けられている動作です。これらは、エンティティの状態を変更する動作です
a)私があなたを正しく理解しているなら、あなたは、エンティティがその属性(すなわち、その状態)を変更する振る舞いのみを含むべきだと言っているのですか?
b)は約何の行動は必ずしも変更しないエンティティの状態を、まだあると考えている固有のものの特性エンティティ(例:吠えるでしょう固有の特性Dog
、それは変更しなかった場合でも、エンティティ犬の状態)?これらの動作をエンティティに含める必要がありますか、それとも他のオブジェクトに移動する必要がありますか?
2)
動作を他のオブジェクトに移動する限り、著者は特に値オブジェクトを参照しています。
私の引用には含まれていませんが、著者は同じ段落で、場合によっては行動(および属性)も他のエンティティに移動することを言及しています(行動をVO に移動する利点は理解していますが)
3)と仮定すると、MyEntity
(質問参照3.私たちはと言うでしょう、SRPを違反しない、私のオリジナルのポストに)責任のはMyEntity
またで構成される他のものの間です。
a。A_resp
+ B_resp
+ AB_resp
(AB_resp
オブジェクトa
を調整し、b
)
または
b。 AB_resp
+委任A_resp
およびB_resp
オブジェクトに(a
およびb
)に関連付けられていますかMyEntity
?
4)Eric EvanのDDDの本、ページ。94:
CustomerIDは顧客ENTITYの唯一の識別子です(図5.5)が、電話番号と住所は顧客の検索または照合によく使用されます。名前は人の身元を定義するものではありませんが、多くの場合、それを決定する手段の一部として使用されます。
この例では、電話と住所の属性が顧客に移動しましたが、実際のプロジェクトでは、その選択はドメインの顧客が通常どのように一致または区別されるかに依存します。たとえば、顧客がさまざまな目的で多くの連絡先電話番号を持っている場合、その電話番号はIDに関連付けられておらず、営業連絡先に残る必要があります。
a)
CustomerIDは顧客ENTITYの唯一の識別子です(図5.5)が、電話番号と住所は顧客の検索または照合によく使用されます。名前は人の身元を定義するものではありませんが、多くの場合、それを決定する手段の一部として使用されます。
引用はアイデンティティに関連している属性だけが実体に残るべきであると述べます。著者は、エンティティがこのエンティティの検索または照合によく使用される属性のみを含むべきであり、他のすべての属性は移動する必要があることを意味すると思いますか?
b)しかし、他の属性はどのように/どこに移動する必要がありますか?例えば、(ここでは仮定は、あるアドレス属性をするために使用されていない見つけたり一致し Customer
、したがって、我々は、移動したいアドレス属性を外にCustomer
):
代わりに有するのであればCustomer.Address
(タイプのstring
)私たちは財産作成Customer.Address
タイプのをAddress
、私たちは移動しなかったアドレス属性を(型である関連したVOオブジェクトにAddress
)か、我々はそれを言うだろうCustomer
、まだ含まれているアドレス属性を?
c)
この例では、電話と住所の属性が顧客に移動しましたが、実際のプロジェクトでは、その選択はドメインの顧客が通常どのように一致または区別されるかに依存します。たとえば、顧客がさまざまな目的で多くの連絡先電話番号を持っている場合、その電話番号はIDに関連付けられておらず、営業連絡先に残る必要があります。
私たちは、多くの各想定した場合以来、ここで間違っにおける作者ではありません連絡先の電話番号Customer
のみ、その特定に属しているがCustomer
、その後、私はこれら言うと思います電話番号が関連付けられているアイデンティティちょうどその時限りCustomer
だけ持っていた1つの電話番号を?
5)
著者がエンティティを削除することを提案する理由は、最初に顧客エンティティを作成するときに、顧客に関連付けられていると考えることができる任意の属性をエンティティに入力する傾向があるためです。これは、最終的に貧弱なドメインモデルにつながる動作を見落とすデータ中心のアプローチです。
オフトピックが、私は思った貧血のドメインモデルの移動からの結果を行動を外のエンティティあなたの例では、投入されている間、実体のたくさんの属性につながる、Customer
あまりにも多くの持つ行動を、我々はおそらくに含めたいので、(行動ましたこれらの追加属性を変更してください)、したがってSRPに違反していますか?Customer
ありがとう