【问题标题】:Strategy for DTO pattern - multiple DTOs per entity or just one?DTO 模式的策略 - 每个实体有多个 DTO 还是只有一个?
【发布时间】:2013-03-14 01:28:07
【问题描述】:

我正在使用 DTO 构建我的第一个应用程序 - 我目前有一个 DTO 用于获取特定对象的数据,还有另一个不同的 DTO 用于更新 (PUTting) 数据 - 因为只有少数字段可以从任何客户端更新,我决定为 PUTting 创建一个专用的 DTO,以避免通过网络发送不必要的数据/字段。这是可维护性方面的良好做法,还是某种禁忌?

【问题讨论】:

    标签: asp.net design-patterns web-applications dto


    【解决方案1】:

    我对多个操作使用相同的类型没有问题。也许您有多个 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(不确定您是否在使用问题)对dynamic inputs 有很强的支持。这可以消除对 DTO 的需求(尽管以减少编译时类型检查为代价)。

    【讨论】:

    • 任何完整的示例应用程序,其源代码在层中使用 DTO、MessageContracts 和 Mappers?
    • @Kiquenet - 抱歉,我不知道有一个示例应用程序可以显示您的请求。
    【解决方案2】:

    这是一个选择问题。我有使用 orm 映射器来减少代码的习惯。我发现预先花时间定义保存并开始使用一个 dto 类可以实现更好的可伸缩性和可维护性,即使这意味着所有字段都得到更新。有边缘情况。如果表使用具有大量 blob 类型数据的字段,那么也许您应该以某种方式对这些更新进行子类化。这是一个见仁见智的问题。

    【讨论】:

      【解决方案3】:

      我确实为每个实体使用多个 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,例如ChangeUserAddressDTOChangeUserLevelDTO

      【讨论】:

        【解决方案4】:

        这不是不可以,但对 CRUD 使用相同的 DTO 会使其在长期内更易于维护。稍后,如果添加和删除新字段,您可能必须更改所有层中的代码。您永远不知道您的客户何时改变主意以编辑更多或更少的数据。

        【讨论】:

        • -1 在可能可以接受的内部层之间,但用于 HTTP 操作的相同 DTO 极不可能是适合 CRUD 的相同类型。无论如何,这不是被问到的问题。
        • -1 为您的 -1。有一个基本假设是您正在通过服务层将对象从数据库层传输到表示层。我同意,这取决于它的架构师是如何设计的,但不是说决定最终必须由知道它的分层方式的人做出。不是你也不是我。
        猜你喜欢
        • 2018-11-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多