C# API中模型与它们的接口设计详解

2020-01-05 09:30:12王冬梅

可编辑的对象

与IChangeTracking不同,IEditableObject专门用于UI场景中。具体地说,就是用在提供确定/取消语义的对话框和数据网格中。

在显示对话框或将数据网格切换到编辑模式之前,必须调用BeginEdit来捕捉对象的快照。EndEdit清除快照,而CancelEdit将对象恢复到之前的状态。请注意,大多数数据网格会自动为你调用这些方法。

如果你同时使用了IEditableObject和IRevertableChangeTracking,那么我建议将其实现为两级撤消,并让IEditableObject处于第二级。或者换句话说,在调用RejectChange时同时调用CancelEdit,但不能反过来。

遗失的属性变更接口

在ORM集成中极有可能缺失一些接口。我们可以使用IChangeTracking来告诉ORM是否需要保存给定的记录,但并没有接口告诉我们哪些属性已经发生改变。这意味着ORM需要单独跟踪发生变更的字段,或者假设所有内容都发生变化,并将整个对象重新保存到数据库。

Equals、GetHashCode和IEquatable

这是我建议避免的一系列特性。根据我们的定义,数据模型是可变的。如果它们是不可变的,那么上述的接口都没有任何意义。

问题是你不能使用可变属性来安全地实现GetHashCode和Equals。字典会假设散列码永远不会改变,所以如果一个对象被当作字典的键,就会破坏字典的功能。

此外,对于数据模型来说,Equality究竟意味着什么?它们代表数据库表中的同一行(即主键)?或者两个对象的每个属性都相同?不管你如何回答这个问题,你的团队中的其他人必定会有不同的答案。