栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > 架构设计

为什么要用impl继承service层

架构设计 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

为什么要用impl继承service层

在分解复杂的软件系统时,架构师和程序员用得最多的技术之一就是分层。个人学习开发的时候,软件系统大多数是三层架构,也就是大家非常熟悉的表现层、领域层(业务层)、数据源层。随着互联网的发展,智能手机普及手机应用越来越多,原本PC端的系统要开始往移动端应用转,那不能从头到尾再开发一套,而后就开始有了微服务架构,然而微服务离不开领域驱动设计,现在大多数开始使用上了四层架构,基础层、用户接口层、应用层、领域层(业务层)。

今天分享内容是软件系统的分层,如何降低层与层之间的依赖。


01 分层的好处与弊端

《企业应用架构模式》里面这样讲到:“当用分层的观点来考虑系统时,可以将各个子系统想像成按照 “多层蛋糕” 的形状来组织,每一层都依托在其下层之上。在这种组织方式下,上层使用了下层定义的各种服务,而下层对上层一无所知。另外,每一层对自己的上层隐藏其下层的细节。因此,第4层使用第3层的服务,第3层使用第2层的服务,第4层无需知道第2层的细节。”

系统分层的好处也非常明显:

· 可以替换某一层的具体实现,只要前后提供的服务相同即可。比如,领域驱动设计中的基础设施层,或者三层架构中的数据源层,我们可以任意的替换,不用考虑底层是数据库,你用的是 hibernate,还是mybatis,或者其它的语言的实现。

· 无需过多了解其他层次,比如,无需知道数据源层和资源库层存储的细节,你只需要告诉它存什么即可。

缺陷:

· 层次并不能封装所有的东西。有时它会为我们带来级联的修改。最经典的例子就是在一个分层设计的企业应用中,如果要增加一个在用户界面上显示的数据域,就必须在数据库中增加相应的字段,还必须在用户界面和数据库之间的每一层做相应的修改。这一点相信做过开发的小伙伴深有体会,每次加一个字段,CRUD都得改一遍。

· 过多的层次会影响性能。在每一层,一般都会从一种表现形式转到另一种。比如VO、DTO、PO等等各种O之间的转换。

02 三层架构

三层架构软件系统开发使用最多的架构之一,如下图

表现层,提供服务,显示信息,比如HTML页面,手机端应用界面,用户请求、点击鼠标,按钮等等。

领域层,业务逻辑的处理,系统中真正的核心部分。

数据层,与数据库、消息系统、事务管理及其他软件包通信,比如,用户注册需要存储数据库,然后写入缓存或者发送邮件通知等等。

这就是我们使用得最多的三层架构,但是最近发现使用了这么久的三层架构发现使用错了。举个案例:这是一个订单业务的的基本包结构,controller 控制层,用来处理前端发送过来的请求,然后调用 service 提供的服务接口,service 调用与数据库打交道的 dao ,每一层都依托于下一层。

事实上这种方式是错的,为什么说错呢。比如,我们大多数采用的是Spring 管理使用依赖注入的方式,service 层 注入 dao 层接口,这样看似没有问题,实际上是将service和dao进行了耦合。我经常用一句大白话说,比如当我们把 dao 那个包删了,你的 service 层报不报红 x,不报则表示 service 层是独立的,报红 x说明有依赖,就这么简单。那如何解决这类问题呢,后面在四层架构中我们来讲。

另外,相信大家都遇到过此类需求,相信大部分也是这样处理的。比如,系统中有一个产品列表,其中,当月销售量比上月销售量大于10%的产品需要用红色显示。为了实现这个功能,开发者在表现层逻辑中比较当月和上月的销售量,然后将差别大于10%的产品显示为红色。

正确的做法是在领域层中定义一个方法,用来指示该产品的销售量是否较上月有较大提高。该方法完成销售量的比较,返回一个布尔值。表现层则只需要简单地调用一下这个布尔方法,如果返回值为真,则用红色凸显。

通过这个案例暴露两个问题,什么是领域逻辑,什么是其他逻辑,这也是使用领域逻辑时,比较困难的。

另外,说出了一个依赖性普遍原则:领域层和数据源层绝对不要依赖于表现层。也就是说,在领域层和数据源层的代码中,不要出现调用表现层代码的情况。

03 四层架构

微服务很火,那微服务架构模式有多种,比如整洁架构、CQRS 和六边形架构等等。那我个人觉得得感谢领域驱动设计的分层架构。

《实现领域驱动设计》一书中这样讲到:“在分层架构中,我们将领域模型和业务逻辑分离出来,并减少对基础设施、用户界面甚至应用层逻辑的依赖,因为它们不属于业务逻辑。将一个复杂的系统分为不同的层,每层都应该具有良好的内聚性,并且只依赖于比其自身更低的层。”

一个DDD传统分层架构,如下图:

领域驱动设计的核心在领域层,另外三层分别为用户层、应用层和基础设施层。

似乎和三层架构没有什么区别,高层依赖于低层。Robert C. Martin 提出 DIP(依赖倒置原则)这样讲到:“高层模块不应该依赖于低层模块,两者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。”

根据依赖倒置原则优化后,如下图:

基础设施层放到了最上方,这样它可以实现所有层中定义的接口。比如,我们要做一个保存订单的操作,不是直接将资源库的接口注入到领域服务,而是注入自身向资源库暴露的接口。

通过这种方式,领域服务层与基础设施层都只依赖于由领域模型所定义的抽象接口。只要抽象接口参数不发生变化,其它层则无需修改。修改范围可以降到最小。把这种方式延伸到三层架构中,你就得到了答案。

最后,简单说一下各层的职责,如下图:

用户层、领域层和基础层和三层架构没有什么区别,重点说一下应用层。

应用层是很薄的一层,理论上不应该有业务规则或逻辑,主要面向用例和流程相关的操作。但应用层又位于领域层之上,因为领域层包含多个聚合,所以它可以协调多个聚合的服务和领域对象完成服务编排和组合,协作完成业务操作。比如,会员结账功能涉及到下单服务、扣卡服务等等,则统一在应用层进行编排组合。

总结,简单讲了软件系统的分层,系统分层的目的是将系统中各部分分离,以降低不同部分之间的耦合度。本文也是个人最近实施领域驱动设计四层架构的一点总结,回头看自己使用三层架构或者传统的架构分层,高层依赖于低层的苦恼,使用依赖倒置原则很好的解决了此问题。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/911781.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号