我正在使用 DTO 构建我的第一个应用程序 - 我目前有一个 DTO 用于获取特定对象的数据,还有另一个不同的 DTO 用于更新(PUTting)数据 - 因为只有少数字段可以从任何客户端更新,我决定为 PUTting 创建一个专用的 DTO,以避免通过网络发送不必要的数据/字段。这是可维护性方面的良好做法,还是某种禁忌?
4 回答
我对多个操作使用相同的类型没有问题。也许您有多个 GET,它们出于类似目的返回类似数据。在那种情况下,没有理由不能重用相同的类型。
但是,您已经确定 GET 和 PUT 操作需要不同的数据。所以它们不仅是不同的操作,而且它们也需要不同的数据。
+----------------+-------------------+--------------------------+
| Similar Data | Similar Purpose | Try to Reuse |
| Similar Data | Different Purpose | Consider; is it logical? |
| Different Data | Similar Purpose | New Type |
| Different Data | Different Purpose | New Type |
+----------------+-------------------+--------------------------+
创建新的 DTO 以满足特定需求还有其他好处,例如:
- 不要让开发人员感到困惑(即使那是你!)
- 不打开安全漏洞,从而填充不打算使用的字段
为了使它更容易:
- 接口可用于帮助强制执行类型之间的公共字段。
- ASP.Net Web API(不确定您是否正在使用您的问题)对动态输入有强大的支持。这可以消除对 DTO 的需求(尽管以减少编译时类型检查为代价)。
这是一个选择问题。我有使用 orm 映射器来减少代码的习惯。我发现预先花时间定义保存并开始使用一个 dto 类可以实现更好的可伸缩性和可维护性,即使这意味着所有字段都得到更新。有边缘情况。如果表使用具有大量 blob 类型数据的字段,那么也许您应该以某种方式对这些更新进行子类化。这是一个见仁见智的问题。
我确实每个实体使用多个 DTO。然而,很多时候我什至没有为视图预定义的 DTO,我只是创建一个匿名类实例,它是使用 Linq 的实体的投影并将其绑定到 GUI。
例如显示用户列表
var users = ... // fetch from DB
ViewData["users"] = users.Select( u => new { Id = u.Id, Name = u.First + " " + u.Last});
显示计分板:
var users = ... // fetch from DB
ViewData["users"] = users.Select( u => new { Id = u.Id, Name = u.Last, Score = u.Score});
这使我免于创建 2 个不同的 DTO。一个潜在的缺点是视图不是强类型的,因此根据 ASP.NET MVC 的版本,我需要将视图模型声明为dynamic
或使用一些ExpandoObject
技巧,但它都被很好地隐藏了。
但是,我总是创建 DTO 来修改状态并将它们视为命令。对于实体上的不同操作,我通常有不同的 DTO,例如ChangeUserAddressDTO
,ChangeUserLevelDTO
等。
它不是不可以,但对 CRUD 使用相同的 DTO 将使其在长期内更易于维护。稍后,如果添加和删除了新字段,您可能必须更改所有层中的代码。您永远不知道您的客户何时改变主意以编辑更多或更少的数据。