• 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.          可以安全地暴露业务模型,不用担心业务方法被非法调用。

  • 相关阅读:
    Failed at the node-sass@4.13.1 postinstall script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
    页面跳转
    多行文字溢出显示省略号
    iview-select选择器组件的使用&设置默认选中的值
    iview中表单验证(遇到的问题)
    iview DatePicker type 为dateTime 时无法做表单验证!
    报错:[Vue warn]: Error in callback for watcher "value": "Value should be trueValue or falseValue."
    Jquery 数字滚动兼容小数
    validate表单验证-单独验证
    2020软件工程作业03
  • 原文地址:https://www.cnblogs.com/ego/p/1456363.html
Copyright © 2020-2023  润新知