前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分层架构

分层架构

作者头像
码农戏码
发布2021-03-23 11:25:20
5610
发布2021-03-23 11:25:20
举报
文章被收录于专栏:DDDDDD

最近连续做了两个新项目,借着新项目的机会,重新审视一下之前一些实践方法,进而寻求一下背后的理论支撑

新项目开始,首先一个就是会新建一个project,那么这个project怎么分层,怎么创建module,怎么分包呢?

经典分层

以传统方式,经典的MVC分层,就controller,service,model

找来一张servlet时代的经典处理流程,虽然技术手段日益更新,但处理流程是一样的

抽象一下,经典的分层就是:

现在大多数系统都是这种分层结构。JavaBean里面只有简单的get和set方法,被很多人鄙视的“贫血模型”;业务逻辑变得复杂时,service会变得很臃肿,出现很多的“上帝类”

回想一下,我们的所有的代码都写在ServiceImpl里面,前几行代码是做validation的事,接下来几行是做convert的事,然后是几行业务处理逻辑的代码,穿插着,我们需要通过RPC或者DAO获取更多的数据,拿到数据后,又是几行convert的代码,在接上一段业务逻辑代码,然后还要落库,发消息…等等

这也是事务脚本开发方式,横行于世。数据与行为被分离。

简单业务这样开发是合适的,但业务一复杂起来,需求频繁变更后,就没人能理解任何一段代码,业务逻辑和技术细节糅杂在一起,业务领域模型没法清晰表达出来,开发人员只知道怎么处理了数据,但背后的业务语义完全不知道

其实呢?还有很多的包,如config,common,core等等, 如果使用了一些中间件,如rabbitmq,还会相应创建上对应的包,简单点可能就被放在了service包下

从有了maven之,module概念更加显现化

代码语言:javascript
复制
<modules>
    <module>service</module>
    <module>common</module>
    <module>core</module>
    <module>test</module>
</modules>

我们的那么多包有了更加明确的地方放置,不再是直接放置在工程目录下

由于上面的这些问题 ,我们似乎可以指出经典的三层架构的弱点:

  • 架构被过分简化,如果解决方案中包含发送邮件通知,代码应该放置在哪些层?
  • 它虽然提出了业务逻辑隔离,但没有明确的架构元素指导我们如何隔离

DDD

虽然技术日新月异,但大多仅仅是技术,带了实现的便利性,但对于业务层次,更多的还是经验。随着业务的复杂性提升,系统的腐化速度和复杂性呈指数上升。

DDD带了很多的认知的改变,最大的好处是将业务语义显现化,不再是分离数据与行为,而是通过领域对象将领域概念清晰的显性化表达出来

当然这世间并没有银弹,但至少能给我们带来一种改进经典分层的理论支撑

DDD中带来了Repository概念,以及基础设施层,再结合【DIP原则】,可以把三层结构变成


再细看一下Controller,这一层,做些什么呢?

轻业务逻辑,参数校验,异常兜底。通常这种接口可以轻易更换接口类型,所以业务逻辑必须要轻,甚至不做具体逻辑

但在现实中,有些更极端,在servlet时代,还做下HttpRequest转换成DTO,传入service,现在有了springmvc,struts2框架的转换,不需要转换了,那么controller成了一个透传层,直接调用service

这儿有两个问题,既然controller是透传,那有必要存在吗?controller调用的service,这个service指的服务是什么呢?

第一controller显然有必要存在,不在于业务,而在于技术实现。不管是http,rpc都得有个请求入口。像thrift可能会比其他的一些rpc框架例如dubbo会多出一层,作用和controller层类似

Tservice与controller的作用是一样的

第二service服务指的是什么?领域服务吗?如果一个复杂的业务,那么会跨越多个领域,自然需要多个领域服务。如果放在controller里面,也就是在controller里面去编排领域服务,如果切换到thrift,那Tservice就得重复

因此,此时需要另一个service,在DDD中就是应用服务

应用服务算是领域服务的facade,应用层是高层抽象的概念,但表达的是业务的含义,领域层是底层实现的概念,表达的是业务的细节


代码语言:javascript
复制
<modules>
        <module>controller</module>
        <module>application</module>
        <module>domain</module>
        <module>infrastructure</module>
        <module>start</module>
</modules>

controller模块:restfull风格的少不了这层

application模块:类似以前的service包

domain模块:如果是事务脚本方式,domain模块就没有了

infrastructure模块:基础模块,类似之前的dao包,但这里面都是实现类,而像repository接口则在domain模块,还需要对应的convertor

模块里面各个包,可能需要按实践情况而定了,后面再从项目中抽取个archetype,使用maven直接生成

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农戏码 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 经典分层
  • DDD
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档