DDD工厂实体值对象(DDD Factory Entity Value Object)

编程入门 行业动态 更新时间:2024-10-18 14:21:32
DDD工厂实体值对象(DDD Factory Entity Value Object)

我在我目前的项目中越来越多地采用DDD /洋葱架构。 我仍然不清楚的许多事情之一是应该有多少封装。 用一个具体的例子更容易解释。

namespace MyProject.Model { public class ComplexEntity { private int _id; public int Id { get {return _id;} } public ValueObjectA ValueA {get; set;} public bool IsBool {get; set;} public ComplexEntity(ValueObjectA a, bool isBool) { // Do some validation first ValueA = a; ValueB = b; IsBool = isBool; } } public class ValueObjectA { public bool IsBoolA {get; private set;} public bool IsBoolB {get; private set;} public ValueObjectA(bool a, bool b) { IsBoolA = a; IsBoolB = b; } } public Interface IComplextEntityFactory { // Option 1 ComplexEntity Create( ValueObjectA a, bool IsBool); // Option 2 ComplexEntity Create( bool valueABool a, bool valueBBool b, bool isBool); } }

对于一个实体的工厂,你呢,

期望调用者为您构造值对象并使用它来初始化ComplexEntity? 基本上将CLR基本类型传递给工厂并构造构成实体的每个ValueObject吗?

我倾向于选择2,但我似乎无法找到它的支持文献。

编辑1

说实话,我仍然不清楚。 聚集根源怎么样?

当我的实体引用其他实体时,例如下面。

我应该有一个IComplexEntityFactory , ILessComplexEntityFactory吗? 或者只是一个IComplexEntityAggregateFactory创建LessComplexEntity并实例化ComplexEntity? 对于AggregateFactory解决方案,如果已传递给工厂的LessComplexEntity属性对应于现有的LessComplexEntity,我该怎么办? 我是否从存储库中检索并重用它? 或者我是否向呼叫者返回错误?

方法签名对于AggregateFactory会是什么? 它是(ValueObject a, ValueObject b)还是(ValueObject value, LessCompelxEntity entity)

public class ComplexEntity {private readonly int _id; public int Id {get {return _id;}}

public ValueObject Value {get; set;} public LessComplexEntity Entity {get; set;} public ComplexEntity(int id, ValueObject value, LessComplexEntity entity) { }

}

public class LessComplexEntity {private readonly int _id; public int Id {get {return _id;}} public ValueObject Value {get; set;} public LessComplexEntity(int id,ValuObject value){}}

I have been increasingly adopting DDD / Onion Architecture in my current project. One of the many things I am still unclear about is how much encapsulation should there be. Easier explained with a concrete example.

Example

namespace MyProject.Model { public class ComplexEntity { private int _id; public int Id { get {return _id;} } public ValueObjectA ValueA {get; set;} public bool IsBool {get; set;} public ComplexEntity(ValueObjectA a, bool isBool) { // Do some validation first ValueA = a; ValueB = b; IsBool = isBool; } } public class ValueObjectA { public bool IsBoolA {get; private set;} public bool IsBoolB {get; private set;} public ValueObjectA(bool a, bool b) { IsBoolA = a; IsBoolB = b; } } public Interface IComplextEntityFactory { // Option 1 ComplexEntity Create( ValueObjectA a, bool IsBool); // Option 2 ComplexEntity Create( bool valueABool a, bool valueBBool b, bool isBool); } }

Question

For the factory of an entity, do you,

Expect the caller to construct the value objects for you and use it to initialize the ComplexEntity? Have essentially CLR basic types being passed to the factory and you construct every ValueObject that makes up the Entity?

I am leaning towards option 2 but I can't seem to find supporting literature for it.

Edit 1

To be honest I am still no clearer. What about aggregate roots?

When my entity refers to other entities, e.g. below.

Should I have an IComplexEntityFactory, ILessComplexEntityFactory? Or just an IComplexEntityAggregateFactory that creates the LessComplexEntity and instantiates ComplexEntity ? In the case of the AggregateFactory solution, what do I do if the LessComplexEntity attribtues that have been passed to the factory correspond to an existing LessComplexEntity? Do I retrieve and reuse it from a Repository? Or do I return an error to the caller?

What would the method signature be for the AggregateFactory? Would it be (ValueObject a, ValueObject b), or (ValueObject value, LessCompelxEntity entity)

public class ComplexEntity { private readonly int _id; public int Id { get { return _id;} }

public ValueObject Value {get; set;} public LessComplexEntity Entity {get; set;} public ComplexEntity(int id, ValueObject value, LessComplexEntity entity) { }

}

public class LessComplexEntity { private readonly int _id; public int Id { get {return _id;} } public ValueObject Value {get; set;} public LessComplexEntity(int id, ValuObject value) { } }

最满意答案

我会选择选项1。

向每个人明确表示您需要使用ValueObjectA来构建ComplexEntity。 当您看到某处使用的方法时,更易读,更少抓头。

如果ValueObjectA发生更改,则必须仅在一个位置(工厂的调用者)修改代码,而不是更改Create()的签名+调整工厂内的值对象创建。

工厂的Create()方法的参数较少,更简洁,更易读。

在单元测试中,它为您提供了更多选项,以便能够注入您想要的ValueObjectA。 如果你将ValueObjectA的创建完全隐藏在工厂中,那么在测试方面你就无法做很多事情。

[编辑]

目前尚不清楚你的真正问题是什么是聚合根和工厂,但你不应该把责任来检索/补充现有对象的责任与创建对象的责任。

作为一般规则,工厂的工作是从较小的部分组装新对象(无论它们是原始类型,值对象,实体......)

工厂应该提供所有这些部件,从某个地方检索或补充它们不是它的责任。 您可以将其留给工厂的来电者。 它将使工厂更具凝聚力,并与更少的类(存储库等)相结合

I'd choose option 1.

Makes explicit to everyone that you need a ValueObjectA to build a ComplexEntity. More readable, less head scratching when you see the method used somewhere.

If ValueObjectA changes, you'll have to modify the code in only one place (the factory's caller) as opposed to changing the signature of Create() + adjusting the value object creation inside the factory.

Less parameters to the factory's Create() method is less verbose and more readable.

In unit tests, it gives you a lot more options to be able to inject the ValueObjectA you want. There's not a lot you can do in terms of testing if you keep ValueObjectA's creation hidden inside the factory entirely.

[Edit]

It's not clear what your real problem is with Aggregate Roots and Factories, but you shouldn't mix up the responsibility to retrieve/rehydrate an existing object with the responsibility to create an object.

I'd take as a general rule that a Factory's job is to assemble a new object from smaller parts (whether they be primitive types, value objects, entities...)

The Factory should be provided with all these parts, it is not its duty to retrieve or rehydrate them from somewhere. You can leave that to the Factory's caller. It will make the Factory more cohesive and coupled to less classes (Repositories, etc.)

更多推荐

本文发布于:2023-07-23 18:37:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1235647.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:实体   对象   工厂   DDD   Entity

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!