zoukankan      html  css  js  c++  java
  • DTO层的思考

     

    注意,【】中是后来加的批注。因为随着对DDD的深入了解,对DTO的思考也有所改变。

    分布式模式下,DTO层是一定需要的吗?

    DTO层的作用是为了隔离Domain Model:让DoMain Model的改动不会直接影响到UI;保持Domain Model的安全,不暴露业务逻辑。

     【最大多数情况看来,UI或者DO的改动,都不可避免地会影响对方,即使中间有DTO隔离,所以这一个理由是不成立的。
    至于安全问题,如果不是开放性平台(业务接口的调用者不是安全的),那么也没必要担心业务逻辑会暴露;即使是开放性平台,我们也可以用AOP做权限检查,限制第三者的非法调用。所以安全问题的理由也不成立。】

    有两个方案可以省略DTO层,又能起到DTO的作用:

    l          继承:定义失血模型的Model,然后再做一个从Model继承的代理类 ,代理类里实现业务逻辑。贫血模型的Model单独为一个DLL,代理模型另起一个DLLClient端只能引用贫血模型的DLL,这样就达到了隔离的目的,又省略了Contract层。

    l          接口:为Domain Model做一个贫血模型的接口,接口单独为一个DLLClient端只引用接口DLL

    这两种方案的核心思想都是让数据字段与业务方法分离,然后只对Client端公开数据部份。但这种思想会导致域模型趋向事务脚本模型,所以都不可取。

     

    综上所述,在使用领域模型的情况下,如果没有DTO层,那么Model是一定会完整地暴露给Client端。

     

    暴露Domain Model会带来什么问题?

    首先是安全问题。

    DoMain Model都带有业务方法,让Client端引用Domain Model就意味着Client端可以绕过Service层直接完成业务逻辑的调用。

     【Client端直接调用Domian Model的方法,甚至直接调用Repository做持久化,在DDD的解决方案中是允许的。至于安全性问题已经在上面反驳过了。】

    其次是效率问题。

    Domain Model通常很“厚”(ModelModel嵌套得很深),在广域网上传输大对象会有严重的效率问题。

     

    再有就是跨平台的问题。

    Domain Model都是与特定的语言的数据类型有关,而这些数据类型是不能跨平台的,比如Java的类型就不能被C#使用。但在分布式模式下,Client端与Server端的平台不同是很正常的,如果Service直接返回Domain ModelClient端根本无法解析,这就要求Service返回的结果必须是标准的格式字节流。

    Domain Model只使用简单类型(字符和数值)?

    让数据类型约束Domain Model显然不是一个好想法,所以DTO似乎是必不可少的了。

     【是的,跨平台是DTO唯一存在的价值,JSON和XML大行其道并不是没有道理的】

    如果我们一定要抛弃DTO层呢?

    我们花这么大力气想省略DTO,就是因为这玩意太麻烦了,而且它的作用如此之小,代价却如此之大。

     

    如果我们的系统只运行在局域网,网络都是光纤,我们有着强大的服务器,而且我们的开发人员严格地遵守Domain Model调用规则,只使用数据字段,不调用业务方法,并且我们的系统使用同一种语言开发,绝对不会跨平台……

     

    我们把一切不利于暴露Domain Model的弱点都屏蔽之后,是不是意味着我们可以省略DTO层了?

    嗯,看起来似乎是可以省略了。但前台开发人员真的能严格遵守调用规则吗?估计这时候,前台开发人员会进而质疑Service层的存在意义了……

     【是的,在DDD中Client端是允许绕过Service,直接访问Domain Model的业务方法,以及Repository层,所以简单模块(只有crud,不用跨领域模块的功能)根本没有Service类。】

    贫血模型 + 事务脚本模式

    贫血模型和事务脚本模式都是与领域模型对立的,领域模型主张充血模型。

     

    便贫血模型+事务脚本模式也有好处:

    1.          开发简单。大多数的开发人员都有用过这种模式——以PetShop为代表的ADO.NET分层构架(MODDALBL)。

    2.          可以安全地暴露业务模型,不用担心业务方法被非法调用。

  • 相关阅读:
    Hibernate---对象的三种状态
    grunt+bower依赖管理
    grunt 的安装和简单使用
    sqlserver dmv 动态管理视图
    ado.net 数据库连接池
    桥接模式
    .net MVP
    主定理(分治算法)
    图中环的判断
    选举协议paxos 协议 理解
  • 原文地址:https://www.cnblogs.com/ego/p/1456363.html
Copyright © 2011-2022 走看看