![](/img/trans.png)
[英]Best practice on determining an aggregate root vs child entities (DDD Modelling)
[英]DDD Root Aggregate with nested entities
| 警告:我省略了部分代碼以提高可讀性(即公共/私有設置器等)
我有:
class Configuration : RootAggregate
{
public string code;
// other fields
public List<Group> Groups;
}
class Group : Entity
{
public string: code;
// other fields
public List<Characteristic> Characteristics;
}
class Characteristic : Entity
{
public string: code;
// other fields
public List<Value> Values;
}
class Value : ValueObject
{
public string code;
public string value;
}
所以我有一個帶有嵌套實體的 RootAggregate。
配置一
__ 最多10人
______ 特性高達 150
__________ 值高達 50
我做了什么:
一起將實體作為參數傳遞給方法(而不是原語)
我不喜歡的是:要更新單個特性的值,我必須首先加載所有組和相關特性,並擔心性能和復雜性,同樣在存儲庫上,我必須有方法用相關實體更新整個配置,對於單個特性的值我必須查詢所有,然后更新特性,然后在所有實體中堅持配置循環並與數據庫協調。
class Configuration : RootAggregate
{
public string code;
// other fields
public List<Group> Groups;
public void AddGroup(Group group)
public void UpdateGroup(Group group)
public void RemoveGroup(string code)
}
class Group : Entity
{
public string: code;
// other fields
public List<Characteristic> Characteristics;
public void AddCharacteristic(Characteristic characteristic)
public void UpdateCharacteristic(Characteristic characteristic)
public void RemoveCharacteristic(string code)
}
class Characteristic : Entity
{
public string: code;
// other fields
public List<Value> Values;
public void CreateValue(string code, string value)
public void UpdateValue(string code, string value)
public void RemoveValue(string code)
}
從組中拆分配置(或配置-> 組並拆分特性-> 值)
我不喜歡的是:-> 這違反了 DDD 原則,因為我必須在添加到配置之前驗證組(對於雙重代碼)。
class Configuration : RootAggregate
{
public string code;
// other fields
}
class Group : RootAggregate
{
public string ConfigurationId;
public string: code;
// other fields
public List<Characteristic> Characteristics;
public void CreateCharacteristic (string code, <other fields>, IEnumerable<Value> values)
public void UpdateCharacteristic (string code, <other fields>, IEnumerable<Value> values)
public void DeleteCharacteristic (string code)
}
class Characteristic : Entity
{
public string: code;
// other fields
public List<Value> Values;
public SetValues(List<Value> values);
}
class Value : ValueObject
{
public string code;
public string value;
}
注意我已經讀過這個類似的問題,但我認為不適用於這種情況。
具有根聚合和 N 嵌套實體級別的 DDD 模式的方法是什么?
在這個特定場景中最好的解決方案是什么?
保存所選解決方案的IRepository
結構是什么?
為了告訴您什么是正確的聚合,我想知道業務需求,而不是您的結構。 在第一個解決方案中對您造成傷害的實際上被稱為 DDD 中的最佳實踐(為了保持一致性,您有義務急切地加載聚合根及其所有嵌套實體)。
我從您的代碼中推斷出,里面有以下業務規則:
Configuration
不應有重復的Codes
。
如果您想將其建模為聚合根,那么我將僅在Configuration
中保留該數據,這確實是保持不變量一致所必需的 - 因此它可能僅保留沒有值的codes
。 因此,使用改進模型的示例代碼:
public void addCode(ConfigurationId configurationId, string code, string value){
Configuration configuration = configRepo.Fetch(configurationId);
configuration.AddCode(code);
Value value = new Value(code, value);
configRepo.Save(configuration);
valueRepo.Save(value);
}
然后你可以操縱值而不必擔心樂觀鎖定和不變量以這種方式被破壞:
public void updateValue(string code, string newValue){
Value value = valueRepo.fetch(code);
value.innerValue = newValue;
valueRepo.save(value);
}
但是,這只是猜測,因為我不知道您的確切不變量。 如果您提供它們,那么我將能夠改進上述代碼。
實現域模型時,深層次結構並不理想。 從概念上講,存在層次結構,但這並不意味着您不能將其拆分為域模型中的不同聚合。
對於事物的讀取方面,您的表示層很可能仍然將層次結構可視化為似乎是單一的事物。
我肯定會采用您的第二種方法。
任何需要具有一致性的東西,例如您的非重復組代碼不變性,您都可以放入適當的聚合中。 您可以在包含聚合中使用標識符或值對象來表示它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.