たくさんの質問をお詫びしますが、それらはユニットとして扱われる場合にのみ最も意味があると感じました
注-すべての引用はDDDからのものです:ソフトウェアの中心にある複雑さへの取り組み(250ページと251ページ)
1)
操作は、コマンドとクエリの2つのカテゴリに大きく分けることができます。
..。
副作用を発生させずに結果を返す演算を関数と呼びます。関数は複数回呼び出すことができ、毎回同じ値を返します。
..。
明らかに、ほとんどのソフトウェアシステムでコマンドを回避することはできませんが、問題は2つの方法で軽減できます。まず、コマンドとクエリをさまざまな操作で厳密に分離しておくことができます。変更の原因となるメソッドがドメインデータを返さず、可能な限り単純に保たれていることを確認してください。観察可能な副作用を引き起こさない方法ですべてのクエリと計算を実行します
a)作成者は、クエリが副作用を生成しないため、クエリが関数であることを意味します。彼はまた、関数は常に同じ値を返すと述べています。これは、同じ入力に対して常に同じ出力が得られることを意味すると思いますか?
b)特定のドメインエンティティQandC(int entityId)
をクエリするメソッドがあり、そこから特定の値を抽出し、それを使用して新しい値オブジェクトを初期化し、このVOを呼び出し元に返すと仮定します。状態を変えないので、上記の引用によると関数ではありませんか?QandC
c)しかし、著者はまた、同じ入力に対して関数は常に同じ出力を生成すると主張しますが、これは、の場合とは異なります。これは、QandC
を複数回呼び出すとQandC
、2つの呼び出しの間の時間にこれが発生すると仮定すると、異なる結果が生成されるためです。エンティティが変更または削除されました。このように、どのように私たちQandC
は関数であると主張することができますか?
d)
変更の原因となるメソッドがドメインデータを返さないことを確認してください...
返される非VOの状態が将来の操作で変更される可能性があり、そのようなメソッドの副作用が予測できないという理由はありますか?
e)
変更の原因となるメソッドがドメインデータを返さないことを確認してください...
エンティティを返すクエリメソッドは、状態を変更しなくても関数と見なされますか?
2)
VALUE OBJECTSは不変です。つまり、作成時にのみ呼び出される初期化子を除いて、それらの操作はすべて関数です。
..。
ロジックまたは計算と状態変更を組み合わせた操作は、2つの別々の操作にリファクタリングする必要があります。しかし、定義上、この副作用の単純なコマンドメソッドへの分離は、エンティティにのみ適用されます。変更をクエリから分離するためのリファクタリングを完了した後、複雑な計算の責任をVALUEOBJECTに移すための2番目のリファクタリングを検討してください。多くの場合、既存の状態を変更する代わりにVALUE OBJECTを導出するか、責任全体をVALUE OBJECTに移動することで、副作用を完全に排除できます。
a)
VALUE OBJECTSは不変です。つまり、作成時にのみ呼び出される初期化子を除いて、すべての操作は関数です...しかし、定義上、この副作用の単純なコマンドメソッドへの分離はENTITIESにのみ適用されます。
著者は、VOで定義されたメソッドはすべて関数であると言っていると思います。これは、VOで定義されたメソッドがそれ自体の状態を変更できない場合でも、他の非VOオブジェクトの状態を変更できるためです。 ?!
b)エンティティで定義されたメソッドが状態を変更しないと仮定すると、エンティティで定義されていても、そのようなメソッドは関数であると見なしますか?
c)
...複雑な計算の責任をVALUEOBJECTに移すために、2番目のリファクタリングを検討してください。
なぜ著者は、複雑な計算を実行する関数のエンティティからのみリファクタリングする必要があると提案しているのですか?代わりに、より単純な関数もリファクタリングすべきではないのはなぜですか?
d)
...複雑な計算の責任をVALUEOBJECTに移すために、2番目のリファクタリングを検討してください。
いずれにせよ、なぜ著者は、エンティティから関数をリファクタリングしてVO内に配置する必要があると提案しているのでしょうか。この操作が関数である可能性があることをクライアントに明らかにするという理由だけで?
e)
多くの場合、既存の状態を変更する代わりにVALUE OBJECTを導出するか、責任全体をVALUE OBJECTに移動することで、副作用を完全に排除できます。
コマンド(つまり、状態を変更する操作)をVOに移動するかどうかを作成者が主張しているように見えるため、これは意味がありません。コマンドが状態を変更している場合でも、本質的に副作用を排除します。それで、どんな考えでも、著者は実際に何を言おうとしていましたか?
アップデート:
1b)
それは視点に依存します。データベースクエリは状態を変更しないため、副作用はありませんが、データが変更される可能性があることを指摘すると、本質的に決定論的ではありません。この本では、著者は、それ自体は外部呼び出しを行わない、値オブジェクトおよびエンティティに関連付けられた関数について言及しています。したがって、ルールはQandCには適用されません。
それで、作者は外部呼び出しを行わない関数だけを説明していました、そしてQandC
それ自体、作者が説明していたタイプの関数ではありませんか?
1c)
QandC自体は状態を変更しません-副作用はありません。ただし、基になる状態は帯域外で変更される場合があります。このため、これは純粋関数ではありません。
しかし、それはまた、作者がそれらを定義したという意味でのサイドエフェクトフリー機能ではありませんか?
1d)
繰り返しますが、これはCQSに基づいています。
私は自分自身を繰り返していることを知っていますが、本の議論はCQSに基づいており、CQSは、いつか(他の操作によって)状態を変更することQandC
によってエンティティが返される可能性があるため、副作用のない機能とは見なされないと思いますQandC
未来?
1e)
CQRSの観点からはクエリと見なされますが、決定論がないため、VOの純粋関数が関数であるという意味で関数とは言えません。
あなたが何を言おうとしていたのかよくわかりません(紛らわしい部分は太字で示されています)。おそらく
QandC
、クエリと見なされますが、エンティティを返すために関数とは見なされず、そのような副作用は予測不可能であり、QandC
本質的に非決定的です。したがって、作成者は 、VOで定義された操作が非VOオブジェクトの状態を変更しようとしないという暗黙の仮定の下で、これらのステートメント( 1eの引用を参照)のみを作成していますか?
2d)
VOは不変であるため、純粋関数を格納するのに適した場所です。これは、ドメイン知識を技術的な制約から解放するためのもう1つのステップです。
関数をエンティティからVOに移動することで、ドメイン知識を技術的な制約から解放するのに役立つ理由がわかりません(技術関連など、技術的な意味もよくわかりません)。
関数をVOに入れる他の理由は、これが関数であることが(クライアントにとって)はるかに明白だからだと思いますか?
2e)
これは、イベントソーシングへのヒントだと思います。既存の状態を変更する代わりに、変更を表す新しいイベントを追加します。正味の副作用はまだありますが、既存の状態は安定しています。
最初にDDDに頭を悩ませたいので、偶数ソースプログラミングについては何も知らないことを告白しなければなりません。とにかく、作成者は、コマンドをVOに移動するだけで副作用が自動的に解消されることを示唆していませんでしたが、代わりにいくつかの追加アクション(イベントソーシングの実装など)を実行する必要があり、その部分について言及するのを「忘れた」だけでした。 ?
2回目の更新:
2d)
エンティティの特徴の1つは、そのアイデンティティです。ビジネスロジックをVOに配置することで、エンティティのアイデンティティのコンテキスト外でそれを考慮することができます。これにより、特にこのロジックのテストが容易になります。
私はあなたが言っていることを理解していますが(距離から概念を考えるとき)、一方で私は実際には理解していません。エンティティ内の関数がこのエンティティのIDによって影響を受けるのはなぜですか(この関数が純粋関数であると仮定すると、つまり、状態が変化せず、決定論的であると仮定します)。
2e)
はい、それは私の理解です-まだ正味の「副作用」があります。ただし、副作用を得るにはさまざまな方法があります。1つの方法は、既存の状態を変更することです。もう1つの方法は、状態の変化を、その変化を表すオブジェクトで明示的にすることです。
私-念のために...あなたの答えから、著者はコマンドをVOに移動するだけで副作用がなくなることを示唆していなかったと思いますか?
II-わかりました。正しく理解していれば、コマンドをVOに移動できます(VOは何の状態も変更しないため、副作用は発生しません)。VO内のこのコマンドは引き続き許可されます。ある種の副作用を生成しますが、この副作用は、状態の変更を明示的にすることで、何らかの形でより受け入れられます(またはより制御可能になります)(変更されたものはVOとして呼び出し元に返されると解釈します)?
3)状態を変更するメソッドSCがドメインオブジェクトを返さない理由をまだよく理解していないと言わざるを得ません。おそらく、非VOは将来の運用で変更される可能性があり、SCの副作用は非常に予測できないためですか?
3番目の更新:
状態の管理をエンティティに委任し、動作の実装をVOに委任すると、特定の利点が生まれます。1つは、責任の基本的な分割です。
a)メソッドがエンティティの動作を記述している(したがって、このメソッドを含むエンティティはSRPに準拠している)ため、エンティティに属している場合でも、それをVOに移動することをお勧めしますか?したがって、本質的に、エンティティの責任を2つのさらに小さな責任に分割しますか?
b)しかし、動作をVOに移行しても、基本的にこのエンティティは単なるデータコンテナになりません(エンティティは引き続きその状態を管理することを理解していますが、それでも...)?
ありがとうございました