文章目录

  • 跨越边界传输数据
    • 分层架构里的数据流
    • 共享领域模型实体
      • 在各层里的领域实体
      • 为命令和查询使用单一模型的危险-补充
      • 将来扩展的可能约束
    • 使用数据传输对象
      • 数据传输对象概论
      • AutoMapper和适配器
  • 总结
  • 笑到最后

跨越边界传输数据

物理层意味着需要跨越的物理边界,不管是进程边界还是机器边界。跨越边界是一个昂贵的操作。触及远程物理机器的代价比触及同一台机器的另一个进程的更高。一个可以参考的经验法则是跨越进程边界的调用比对应的进程内调用要慢100倍。如果要通过网络传输才能到达端点的话就更慢了。
一个调用是如何通过网线跨越边界的?轻装传输?还是背负一切传输?选择最适合的方式跨越边界(逻辑的或物理的)传输数据是应用程序的业务部分要解决的另一个设计问题。

分层架构里的数据流


上图(跨越分层架构各层的数据流的示意图)展示了分层架构里的一个相对抽象的数据流。

  1. 数据从用户界面以InputModel的形式穿过应用程序层。
  2. 根据被请求的操作,应用程序层可能需要使用InputModel的内容创建领域实体(比如说,从提供的信息创建一个新的订单)。
  3. 在分层的领域模型系统里,持久化通常意味着把领域实体转换成物理数据模型(通常是关系型数据模型)。
  4. 在回来的路上,在请求查询时,从数据模型读到的内容首先会被转换成领域实体图,然后适配进视图模型给用户界面渲染。

这4种模型在逻辑上都是不同的,但有时候它们可能是重合的。领域模型可以直接持久化到基础设施层,在这种意义上,领域模型和数据模型通常是相同的。在ASP .NET MVC应用程序里,输入模型和视图模型在控制器操作的GET和POST实现里通常是重合的。在CRUD系统里,所有模型都可能重合,也就是只有一个一一一它将会是MVC模式里的“模型”。

早在20世纪80年代刚被设计出来时,MVC是一个应用程序模式,可以用来架构整个应用程序。那是一体化系统的年代,被端到端创建成单一事务脚本。多逻辑层和多物理层系统的出现改变了MVC的角色,但没有否定它的重要性。MVC仍是一个强大的模式,但单一模型的理念不再有效。MVC里的模型被定义为“在视图里使用的数据"。这意味着今天的MVC基本上是一个表现模式。

共享领域模型实体

在遵循领域模型模式的分层架构里,领域实体是最合适的输入容器。领域实体是否适合向上传
给用户界面,并在需要时序列化它们穿越物理层?
此外,在数据驱动的应用程序里,如果你要把领域模型传给表现层(某种自我跟踪的实体),那
么贫血领域模型更加适合。
当你在类里使用带有方法的富模型(领域模型)时,把领域实体传给表现层没有意义,因为这会
让表现层得以实体里的那些方法。在DDD应用程序里,表现层应该有一个不同的表现模型,基于DTO
模型(在很多情况下是一个视图模型),DTO是根据屏幕/页面的需求而不是基于领域模型来设计的。

在各层里的领域实体

我们认为在应用程序层编排的组件和模块之中传递领域模型的类是没有问题的。只要数据传输
135

发生在逻辑层之间,就应该没有问题,不管是技术上的还是设计上的。如果数据传输发生在物理层
之间,你可能会遭遇序列化问题,尤其是领域实体构成了一个错综复杂的图,里面还有循环引用。
在这种情况下,引入一些专门的数据传输对象针对一两个场景进行处理可能更加容易。
湖注意:确切地说,当实体具有延迟加载属性时,在不同的逻辑层之间传输领域实体也可能面临
问题。在这种情况下,当接收实体的层试图通过延迟加载属性读取数据时,就会引发异常,因为数
据还没加载,而存储环境已经不再可用。

领域模型(Domain Model)实体包含的内容与用户界面(View Model)一致,可以在用户界面使用Domain Model,省下一堆其他的数据传输类。原则上,在各个逻辑层和物理层上使用领域模型实体不但可以接受,在某些情况下更是合适的,但是,有一些可能的副作用需要考虑。

为命令和查询使用单一模型的危险-补充

从下一章开始我们会探讨这个问题,在第10章“CQRS导论”和第11章“实现CQRS”里会有 更深入的讨论。

就目前而言,从用户界面引用领域实体可能需要表现层代码充分利用领域实体内建的行为。这个行为本质上就是领域逻辑,而领域逻辑必须一直与业务规则保持一致,我们认为表现层代码有打破这个一致性的潜在风险。

将来扩展的可能约束

由于现代应用程序会扩展新的前端。这可能需要为用户界面提供数据的不同聚合,而这些聚合并不存在于领域模型里。如果不想为了满足特定前端的需要而修改领域模型。可以添加专门的数据传输对象(DTO)。

使用数据传输对象

有时候,使用领域实体可能很方便;有时候,使用数据传输对象(DTO)会更好。没有哪个解决方案总比其他的好。需要具体问题具体分析。

数据传输对象概论

数据传输对象专门用来在不同的物理层之间携带数据。DTO没有行为,只是一个简单的get和set的容器,创建起来也相对不昂贵(比如说,它不需要单元测试)。作为一个简单容器,使用DTO的原因是它允许你打包多块数据,在单次往返里传输所有数据。DTO与生俱来就是可序列化对象。在涉及远程组件时通常都推荐用它。但是,我们希望从一个
更广泛的角度来看待DTO,考虑在不同的逻辑层之间使用。

2.DTO与领域实体
DTO的通常用法是,举个例子,当你需要同时显示或处理订单和客户信息,但实际处理所需的信息只用到订单和客户实体上的一部分属性。DTO可以把复杂的层次结构简化成简单的数据容器,只包含必要的数据。

图7.4在跨越不同的物理层和逻辑层传输数据时的DTO与领域实体

在不同的逻辑层共享领域实体通常是没问题的,而且可以最大限度减少牵涉的类的总量。从单纯的设计角度来看,使用DTO是“完美的”解决方案,它保证了接口组件之间最大程度的解耦,也保证了可扩展性。

但是,完整的DTO解决方案毫无疑问会导致各个VisualStudio项目出现大量的小类。一方面,你需要通过文件夹和命名仝间来管理和组织那些数量可观的类。另一方面,你也不得不面对把数据加载到DTO以及从DTO提取数据的代价。

AutoMapper和适配器

使用DTO真正的代价就是数据填充以及读取数据。AutoMapper可以把属性从领域实体复制到DTO,反之亦然。使用示例

// 源类型和目标类型之间创建一个映射,启动映射过程,用源类型的实例里的数据填充目标类型的实例
mapper.CreateMap<YourSourceType,YourDtOType>();
// 通过Map方法调用它
var dto=Mapper.Map<YourDtOType>(sourceObject);

AutoMapper这类自动化工具的缺点:
当用它从实体创建DTO时,无可避免地要遍历整个实体图,为此必须把整个实体图从存储读到内存里。或许,通过领域服务返回现成的DTO更加便捷。

注意:另一个传输数据的方案是使用IQueryabIe对象。一个极具争议但正在普及的做法是从数据仓储返回IQueryable。
IQueryable是LINQ的核心接口,它所做的是针对支持LINQ的数据源提供计算查询的功能。
从仓储返回IQueryable的一个原因是让上层可以轻易创建不同类型的查询。这样做可以保持仓储接口轻薄,同时减少使用DTO的需要,因为某些DTO可以是匿名类型。虽然DTO是从查询创建的,但它们属于特定的层,隔离在层的上下文里,并且易于管理。

总结

经典的二元论:做正确的事与正确地做事。它们没有谁比谁更优先,二者都是重要的观点。

正确地做事是表现层应该关心的事。正确地做事的核心理念是效率:以优化的方式实现任务,快速且流畅。做正确的事则是业务层应该关心的事。做正确的事的核心理念是效益和达成目标。软件系统的终极目标是满足需求和忠实再现领域空间。

为了使得领域建模更加高效,领域模型等模式和IDDD等方法学是必不可少的。这些方法学对多年以来被称为业务层的东西进行了改造。我们引入了应用程序层和领域层,同时把数据访问和其他基础设施组件(如邮件服务器、文件系统和外部服务)都隔离到基础设施层里。

我们在这里提及的领域模型模式都是比较通用的内容,在下一章里,我们将会着重探讨领域驱
动设计。

笑到最后

一个成功的业务层需要敏锐的观察和建模。它还需要通过尽可能简单的方式做事的能力。“简约而不简单”是我们最喜欢的真言之一。此外,我们为本章列出的第一条墨菲定律是:如果你有任何复杂的东西可以工作,那么你可以肯定过去也有某些简单的东西可以工作。
一个可以工作的复杂系统总是从一个可以工作的简单系统进化而来的。
在软件可靠性上的投入会持续增加,直到超出错误的可能代价。
理论和实践在理论上没有区别,但在实践上有。

业务层——跨越边界传输数据相关推荐

  1. 走向.NET架构设计—第四章—业务层分层架构(后篇)

    走向.NET架构设计-第四章-业务层分层架构(后篇) 前言: 在上一篇文章中,我们讨论了组织业务逻辑的模式:Transaction Script和Active Record,Domain Model. ...

  2. 什么是业务逻辑层(业务层)及业务逻辑层(业务层)的功能

    转载地址:http://www.cnblogs.com/whitewolf/archive/2012/05/29/2524881.html 业务逻辑层是专门处理软件业务需求的一层,处于数据库之上,服务 ...

  3. 13.业务层的事务操作

    业务层使用到事务操作时,使用ThreadLocal方法. 在Hibernate工具类中添加静态变量TheadLocal private static TheadLocal session = new ...

  4. tcp业务层粘包和半包理解及处理

    tcp粘包处理 tcp是流式传输的,是安全的, 可靠的,顺序的. udp是数据报协议,是不可靠的. 面试中经常被问到tcp粘包是如何处理的,通过百度和自己的理解,这里做笔记记录. 如果有不对,请指正~ ...

  5. java-web分层2-Bean和业务层

    上次我们说的是Dao层,那么这次我们来看javaBean层和业务层要实现怎样的功能,之前说的是dao层的任务是和数据库进行交换,可以在某个具体的实体类的DaoImpl对数据进行操作,比如说我们某一个数 ...

  6. java 业务层业务接口层_Java web五层架构

    DAO层: 1.DAO层--[面向表]: 持久层.数据访问层,主要与数据库进行交互 介绍: DAO层只是封装增删改查,比较底层,比较基础的操作,具体到对于某个表.某个实体的增删改查.至于增删查改如何去 ...

  7. J2EE业务层模式:服务门面,应用服务,以及业务委托,服务定位器

    现在J2EE领域无论是表现层,业务层还是持久层,框架满天飞,虽然说框架为我们省了很大的力气,但是我们还是需要掌握J2EE里面经常用到的一些模式,下面对J2EE领域业务层的几个模式做一个小的总结: 服务 ...

  8. 架构语言ArchiMate -业务层(Business Layer)

    在线ArchiMate1.0中对ArchiMate进行了详细的介绍,想学习的一些同事不太喜欢看英文资料,而年后项目组要开始做业务架构了,所以在春节前最后一天把对业务层的介绍写完.以下我将会分别对不同层 ...

  9. 如何快速分析一款ios软件或需求的大流程,然后在业务层实现,不牵扯到界面?...

    如何快速分析一款ios软件或需求的大流程,然后在业务层实现,不牵扯到界面? 转载于:https://www.cnblogs.com/ygm900/p/3479260.html

  10. 走向.NET架构设计—第四章—业务层分层架构(前篇)

    走向.NET架构设计-第四章-业务层分层架构(前篇) 前言:在任何一个项目中业务层毫无疑问是最重要的层,所以在设计的过程中,如何组织业务层是至关重要的.本章的讨论将会涉及Flower的架构模式一书中的 ...

最新文章

  1. mysql备份和还原数据库
  2. Bzoj-2820 YY的GCD Mobius反演,分块
  3. 控制for each循环次数_CCF CSP编程题解201312-1:出现次数最多的数
  4. 鸿蒙开源源码,基于鸿蒙系统开源项目OpenHarmony源码静态分析
  5. java什么是接口_Java接口是什么
  6. Linux下用户组、文件权限、更改目录下所有文件权限
  7. python声明匿名函数_举例讲解Python的lambda语句声明匿名函数的用法
  8. 苹果Mac好用的图片编辑工具:Acorn 再升级
  9. 量子计算机未来猜想,太厉害了吧?这台量子计算机能预测16种不同的未来!
  10. 小程序开发合同_如何开发微信小程序?
  11. 如何将一个mp3文件平均分割成三个?
  12. Android 百度翻译API(详细步骤+源码)
  13. Broker启动历史数据加载
  14. 复杂网络盘传播搜索关键字
  15. 2013年企业邮箱的发展:任重而道远
  16. 夏商周秦西东汉 三国两晋南北朝 隋唐五代和十国 辽宋夏金元明清
  17. 死链接检查工具:Xenu 使用教程
  18. [Swift]地图导航
  19. linux mint 划动鼠标快捷截图
  20. html 表格 锁定首行,教你实现首行及首列固定 Table

热门文章

  1. 4775电子书免费链接
  2. 数据库服务器型号类型,数据库服务器型号
  3. 动易 mysql_动易数据转成dedecms的php程序
  4. 视频教程-【孙伟】网页设计(切图)视频教程-UI
  5. Qt5.12 安装教程windows
  6. SIR模型的应用 - Influence maximization in social networks based on TOPSIS(3)
  7. 零基础考公务员,备考多长时间最合适?
  8. 优先部署EDI系统把握信息传输的主动权
  9. 如何对接GN EDI系统?
  10. SpringBoot + Vue 简单实现学生饭卡管理系统