Collections DDD和集合

Collections DDD和集合,collections,domain-driven-design,Collections,Domain Driven Design,假设我有一个域类: public class Country { string name; IList<Region> regions; } public class Region { string name; IList<City> cities; } etc. 公共类国家 { 字符串名; IList地区; } 公共类区域 { 字符串名; 爱尔兰城市; } 等 我想在GUI中以树的形式对此进行建模 public class Node<

假设我有一个域类:

public class Country
{
   string name;
   IList<Region> regions;
}

public class Region
{
   string name;
   IList<City> cities;
}

etc.
公共类国家
{
字符串名;
IList地区;
}
公共类区域
{
字符串名;
爱尔兰城市;
}
等
我想在GUI中以树的形式对此进行建模

public class Node<T>
{
  T domainObject;
  ObservableCollection<Node<T>> childNodes;
}

public class CountryNode : Node<Country>
{}

etc.
公共类节点
{
T域对象;
可观察收集子节点;
}
公共类CountryNode:节点
{}
等
如何自动检索国家/地区的地区列表更改、地区的城市列表更改等

一种解决方案是在域类上实现INotifyPropertyChanged并将IList更改为ObservableCollection,但这感觉有点错误,因为为什么我的域模型有责任通知更改

另一种解决方案是将这一责任放在GUI/表示层上,如果某个操作导致将某个地区添加到某个国家,则表示层应将新的国家添加到CountryNode.ChildNodes和domain Country.Regions


对此有何想法?

将InotifyProperty转换为解决方案是在模型中实现事件的一部分。从本质上讲,赛事本身并没有与DDD咒语脱节。事实上,这是埃文斯暗示的东西之一,而这正是他早期材料中缺失的东西。我不记得确切的位置,但他在这段视频中提到了它

就其本身而言,推动事件模型在域中实际上是合法的,因为它在域和系统中的其他代码之间引入了解耦。你所做的只是说,你的领域有能力通知感兴趣的各方某些事情已经发生了变化。因此,认购人有责任对其采取行动。我认为混淆之处在于,您只使用INotifyPropertyChanged实现来中继回事件接收器。然后,该事件接收器将通过已注册的回调通知所有订阅者“发生了什么”

然而,话虽如此,你的情况是一种“边缘”情景,而事件并不完全适用于这种情景。您正在查看当列表本身更改时是否需要重新填充UI。在工作中,我们当前的解决方案使用了一个可观察的集合。虽然它确实有效,但我不是它的粉丝。另一方面,发布列表中的一个或多个项目已更改的事实也有问题。例如,您如何确定列表的熵以最好地确定它已更改

因为这样,我会认为这不是一个领域的关注。我不认为您所描述的是域所有者的需求,而是应用程序体系结构的产物。如果在进行更改后查询域中的服务,它们将正确返回,应用程序仍将是不同步的。在这个时刻,在这个领域的世界里实际上没有什么错误

所以,有几种方法可以让我看到这一点。最低效的方法是直接针对模型持续轮询更改。您也可以考虑使用某种标记来指示列表是脏的,尽管不使用域模型来这样做。再一次,这不是一个干净的解决方案。但是,您可以在领域之外应用这些原则,以提出一个有效的解决方案

如果您有某种共享缓存机制,即分布式缓存,则可以实现JIT缓存/逐出方法,其中插入和更新将使缓存无效(即逐出缓存项),随后的请求将加载它们。然后,您可以将一个标记放入缓存本身,该标记将指示可识别的内容,以确定该项何时重建。例如,如果您有一个包含区域ID列表的缓存项,则可以存储它被JIT的日期时间。然后,应用程序可以跟踪它的JIT-ed版本,并且只有在看到版本已更改时才重新加载。您仍然需要轮询,但这样做可以避免将该责任放在域本身,如果您只是轮询少量数据,那么这比每次都重建整个数据要好


另外,在总体设计完整的解决方案之前。解决域所有者的问题。他/她/他们可能完全可以接受你只是在某处有一个“刷新”按钮或菜单项。这也是一个折衷方案,我敢肯定大多数域所有者都会优先考虑核心功能而不是某些类型的问题。

将InotifyProperty更改为解决方案是在模型中实现事件的一部分。从本质上讲,赛事本身并没有与DDD咒语脱节。事实上,这是埃文斯暗示的东西之一,而这正是他早期材料中缺失的东西。我不记得确切的位置,但他在这段视频中提到了它

就其本身而言,推动事件模型在域中实际上是合法的,因为它在域和系统中的其他代码之间引入了解耦。你所做的只是说,你的领域有能力通知感兴趣的各方某些事情已经发生了变化。因此,认购人有责任对其采取行动。我认为混淆之处在于,您只使用INotifyPropertyChanged实现来中继回事件接收器。然后,该事件接收器将通过已注册的回调通知所有订阅者“发生了什么”

然而,话虽如此,你的情况是一种“边缘”情景,而事件并不完全适用于这种情景。您正在查看当列表本身更改时是否需要重新填充UI。在工作中,当前的解决方案是