代码之家  ›  专栏  ›  技术社区  ›  blockhead

访问视图中的域对象

  •  3
  • blockhead  · 技术社区  · 15 年前

    如果我不想公开我的域对象的内部状态,但是我需要显示它们,我可以考虑三种方法。 哪一个是最“正确的”(如果有的话?).

    1. “DTO/ViewModel方法”。 这似乎是一种流行的方法 在ASP.NET MVC世界中(尤其是 使用automaper)。
    2. 这个 “装饰方法”。如果我有 “客户”实体,我装饰它 有一个“可显示的客户”可以 访问的内部状态 客户(在大多数语言中, 我已经处理过了)。
    3. “界面” 接近“。在那里我做一些类似的事情 这是:

      class Customer {
          ....
          public void renderWith(CustomerRenderer renderer) {
               renderer.renderCustomer(address,name);
          } 
      }
      
      interface CustomerRenderer {
          public void renderCustomer(Address address, Name name);
      }
      
    1 回复  |  直到 15 年前
        1
  •  3
  •   Community SushiHangover    7 年前

    我支持并广泛使用你的1号选择。原因如下:

    • 允许使用复杂的视图模型,例如组合域对象的多个列表。考虑一个post元素和挂起的ilist容器的postviewModel。
    • 在我当前的项目中,我们已经将域验证抽象到自定义视图模型中,并对表单进行了一些巧妙的Ajax验证。
    • 虽然这个概念不会直接在模型上公开您的域对象,但是挂起PostViewModel属性的Post没有问题。

    最后一点是为什么视图模型概念确实存在。将域对象一直公开到您的UI甚至视图中并不是违反DDD的,这是DDD和UI概念的设计和期望。您只公开要使用的域中的对象,并通过服务和基础结构锁定/保持它们的状态。因此,您没有违反在您的UI中使用实际的域对象。

    这时,您需要为您的UI引入MVC概念,并尝试呈现页面/位置的特定视图。您可能(并且将)拥有与域完全无关的其他显示元素,例如 Progress Bar 这只适用于用户界面。进度条只关心UI和应用程序层。这与你的域名无关。

    因此,我接受的DDD解决方案是在应用程序/ui层中使用一个hybird对象,该对象可以容纳多个对象:域对象和应用程序对象,以便为该特定视图呈现。这就是视图模型的概念,也是其存在的核心原因。

    可视模型概念可以被认为是DDD术语中的应用程序层非业务对象。


    稍微偏离主题,谈论一种特定的技术,ASP.NET MVC还有其他的特性来帮助使这个概念能够很好地协同工作。它不是直接内置在ASP.NET MVC中的,而是作为Microsoft的附加程序集提供的,称为Futures项目。

    Check out my blog post about a couple of features ,最有用的功能是“渲染延伸”方法:

    http://eduncan911.com/blog/html-renderaction-for-asp-net-mvc-1-0.aspx

    这是一个非常强大的概念,它使底层控制器旋转并调用action方法。这样做大大简化了我们的视图模型,只关心它们渲染的视图。我不再需要附加侧边栏控件或其他与视图无关的常用数据框、导航栏等内容。

    renderaction与renderpartial不同,原因纯粹是DDD:它允许您将业务逻辑移回它所属的控制器中。控制器调用适当的视图来呈现它的显示。这严格遵循DDD和MVC概念。

    微软已经声明,明年发布时,renderAction将是ASP.NET MVC 2.0的一部分。

    对不起你的咆哮…