我最近开始探索域驱动设计,并有一个问题。假设我的应用程序中有产品,类别,制造商域模型。产品看起来像这样:
Repeater
{
model: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
CheckBox
{
function isChecked() {
return ((days & (1 << index)) != 0);
}
text: modelData
checked: isChecked()
onClicked:
{
if (checked) {
days |= (1<<index);
}
else {
days &= ~(1<<index);
}
// now rebind the item's checked property
checked = Qt.binding(isChecked);
}
}
}
通常在显示产品的详细信息视图中,会显示类别名称和制造商名称(而不是其ID)。但是类别和制造商是不同的聚合。问题是如何获取制造商和类别名称以及产品领域模型。 ProductRepository只返回Product域Model(以及categoryId和ManufacturerId)。
但我不需要所有的属性,我只需要他们的头衔。我面临着与所有领域模型类似的问题。
请帮助我该如何解决这个问题。
答案 0 :(得分:2)
有多种方法可以解决这个问题:
本地缓存/查看模型
在服务中本地保留一个内存缓存,该服务在CategoryId和CategoryTitle之间进行映射(对于制造商而言相同) - 这可以通过:
对数据进行非规范化
您可以通过将CategoryTitle与CategoryId一起保存来复制数据。这样您就无法调用外部服务。权衡是你需要考虑CategoryTitle可能改变的频率,以及你如何处理这种变化。
举报“域名”
您可以拥有一个完全独立的服务,用于侦听来自其他服务的数据并维护UI的视图模型。这将使您的其他服务不了解其他服务的顾虑。使用事件驱动系统时,您将从其他服务中侦听事件,以便为UI构建视图模型
答案 1 :(得分:0)
除了@ tomliversidge的回答,我建议您查看复合UI 模式(您可以找到示例here)。
您将有一个服务网关构建一个复合视图模型,其中包含来自3个服务(产品,制造商和类别)的信息。
答案 2 :(得分:0)
通常在显示产品的详细信息视图中,会显示类别名称和制造商名称(而不是其ID)。 ...问题是如何获取制造商和类别名称以及产品领域模型。 ProductRepository仅返回Product domain Model(以及categoryId和ManufacturerId)
如我所见,“类别名称”和“制造商名称”用于显示,因此它与演示文稿有关。 我建议只为该屏幕提供单独的阅读模型(参见Command Query Responsibility Segregation (CQRS)):
public class ProductReadModel
{
int ProductId;
string Title;
string Description;
double Price;
string CategoryName;
string ManufacturerName;
}
有不同的方法来填充/构建该模型:
如果我们的聚合使用ORM(例如NHibernate)保存在关系数据库中,那么您可以使用原始SQL或轻量级ORM(例如Dapper)直接查询数据库。您不需要存储库,只需要QueryHandler
如果我们的聚合是事件来源,那么您只需听取域事件(例如CategoryNameChanged
/ ManufacturerNameChanged
),然后将它们投影(非规范化)到ProductReadModel
并存储它在任何存储空间(甚至在内存中)。
如果您的聚合在关系数据库中持久存在,您还可以触发和项目/非规范化域事件。