关系经济人类预测化学自然
投稿投诉
自然科学
知识物理
化学生物
地理解释
预测理解
本质社会
人类现象
行为研究
经济政治
心理结构
关系指导
人文遗产

ThinkinginDDD(二)

7月27日 圆通道投稿
  DDD的落地,主要有三个方面需要理清:第一,以何种应用架构进行落地;第二,核心组件及其生命周期,相互之间的交互逻辑;第三,不同限界上下文之间如何集成。
  本文将重点分析DDD落地的应用架构,其余两个方面后续会专门去展开。
  DDD的实现架构有很多,有经典四层架构、六边形(适配器端口)架构、整洁架构(cleanarchitecture)、CQRS架构等,相信很多读者跟我刚开始接触时一样,完全不知道该选择什么架构进行落地。
  本文不会逐个去讲解这些架构,而是从我们日常的三层架构出发,带领大家思考适合我们落地的架构。
  我们很多项目是基于三层架构的,其结构如图:
  我们说三层架构,为什么还画了一层Model呢?因为Model只是简单的JavaBean,里面只有数据库表对应的属性,有的应用会将其单独拎出来作为一个maven模块。
  接下来我们开始对这个三层架构进行抽象精炼。第一步,数据模型与数据访问层(持久层)合并
  为什么数据模型要与数据访问层合并呢?首先,数据模型与数据库表结构的字段是一一对应的,数据模型最主要的应用场景就是持久层用来进行ORM,给Service层返回封装好的数据模型,供Service执行业务;其次,数据模型的Class或者属性字段上,通常带有ORM框架的一些注解,跟持久层联系非常紧密,根据单一职责的原则,我认为数据模型就是持久层拿来查询或者持久化数据的,数据模型脱离了持久化层,意义不大。第二步,从Service抽取业务逻辑
  常见的Service方法,既有缓存、数据库的调用,也有实际的业务逻辑,整体过于臃肿。
  先看现在的Service方法的伪代码:publicvoidbusinessLogic(Paramparam){if(checkParam(param)){thrownewXXXException();}DatadatanewData();或者是mapper。queryOne(param);data。setId(param。getId());if(condition1true){biz1biz1(param。getProperty1())data。setProperty1(biz1);}else{biz1biz11(param。getProperty1())data。setProperty1(biz1);}if(condition2true){biz2biz2(param。getProperty2())data。setProperty2(biz2);}else{biz2biz22(param。getProperty2())data。setProperty2(biz2);}一堆set方法mapper。updateXXXById(data);cache。del(data);删除缓存mpPublisher。publish(data);发出消息}
  这是典型的事务脚本的代码:先做参数校验,然后通过biz1、biz2等子方法做业务,并将其结果通过一堆Set方法设置到数据模型中,再将数据模型更新到数据库。
  由于所有的业务逻辑都在Service方法中,造成Service方法非常臃肿,Service需要了解所有的业务规则,并且要清楚如何将基础设施串起来。同样的一条规则,例如if(condition1true),很有可能在每个方法里面都出现。
  我们知道,专业的事情就该让专业的人干。既然业务逻辑是跟具体的业务场景相关的,我们想办法把业务逻辑提取出来,形成一个模型,让这个模型的对象去执行具体的业务逻辑,即提供业务能力。这样,Service方法就不用再关心里面的ifelse业务规则,只需要给业务模型执行的舞台,并提供基础设施完成用例即可。
  将业务逻辑形成模型了,这样的模型,就是领域模型。
  我们先不管领域模型怎么得到,总之,拿到Service方法的入参之后,我们通过某种途径得到一个模型,我们让这个模型去做业务逻辑,最后执行的结果也都在模型里,我们再将模型写回数据库,当然,怎么写数据库的我们也先不管。
  抽取之后,将得到如下的伪代码:publicvoidbusinessLogic(Paramparam){if(checkParam(param)){thrownewXXXException();}DomaindomainloadDomain(param);domain。doBusinessLogic();saveDomain(domain);cache。del(domain);删除缓存mpPublisher。publish(domain);发出消息}
  根据代码,我们已经将业务逻辑抽取出来了,领域相关的业务规则封闭在领域模型内部。此时Service方法非常直观,就是获取模型、执行业务逻辑、保存模型,再协调基础设施完成其余的操作。
  抽取完领域模型后,我们工程的结构如下图:
  第三步,维护领域对象生命周期
  在第二步中,loadDomain、saveDomain两个方法还没有得到讨论,这两个方法跟领域对象的生命周期息息相关。
  不管是loadDomain还是saveDomain,我们一般都要依赖于数据库或者其他中间件,所以这两个方法对应的逻辑,肯定是要跟DAO产生联系的。而保存或者加载领域模型,我们可以抽象成一种组件,这种组件就是Repository。
  注意,Repository加载或者保存领域模型,方法的入参或者出参,一定是基本数据类型或者领域内定义的类型,而不能是表数据模型。
  以下是Repository的伪代码:publicinterfaceDomainRepository{voidsave(Domaindomain);Domainload(DomainIdid);假设是领域模型ID,也可能是其他的入参}
  既然DomainRepository与底层数据库有关联,但是我们现在DAO层并没有引入Domain这个包,DAO层自然无法提供DomainRepository的实现,我们初步考虑可以将这个DomainRepository实现在Service中。
  我们再推敲推敲,如果我们在Service中实现,势必需要在Service中操作数据模型:查询出来数据模型再封装为领域模型、或者将领域模型转为数据模型再通过ORM保存,但这个过程不该是Service层该关心的。
  所以,我们决定在DAO层直接引入Domain包,并在DAO层提供DomainRepository接口的实现,DAO层的Mapper查询出数据模型之后,封装成领域模型供DomainRepository返回。
  此时DAO层不再向Service返回数据模型,而是返回领域模型。
  现在,我们项目的架构图是这样的了:
  第四步,泛化
  在第三步中,我们的架构图已经跟经典四层架构非常相似了,我们再把格局放大点,对整个架构进行泛化抽象。
  首先,DAO层其实属于基础设施层,只不过其职责是持久化和加载聚合,所以,我们将DAO层改名为InfrastructurePersistence,可以理解为基础设施层持久化包。之所以采取这种InfrastructureXXX的格式进行命名,是由于Infrastructure可能会有很多的包,分别提供不同的基础设施支持。一般的项目,还有可能需要引入缓存,例如Redis,我们就可以再加一个包,名字叫InfrastructureCache或者InfrastructureRedis。
  注意:为了确保领域层知识的完备,Infrastructure层应该实现Domain层定义的基础设施接口,而不是向上层提供没有在领域层定义过的组件。
  然后,Controller层其实就是用户接口层,即UserInterface层,我们在项目叫Interfaces。Controller层的名字有很多,有的叫Rest,有的叫Resource,考虑到我们这一层不只是有Rest接口,还可能还有一系列的拦截器,所以我一般比较随意的称之为Web。因此,我们将其改名为InterfacesWeb,即用户接口层的Web包。同样,我们可能会有很多的用户接口,但是他们通过不同的协议对外提供服务,因而被划分到不同的包中。我们如果有对外提供的RPC服务,那么其服务实现类所在的包就可以命名为InterfacesProvider。
  有时候引入某个中间件,既会增加Infrastructure也会增加Interfaces。例如,如果引入Kafka就需要考虑一下,如果是给Service层提供调用的,例如逻辑执行完发送消息通知下游,那么我们再加一个包InfrastructureP如果是消费Kafka的消息,然后调用Service层执行业务逻辑的,那么就可以命名为InterfacesSubscriber。
  最后,Service层目前已经没有业务逻辑了,业务逻辑都在Domain层去执行了,Service只是提供了应用服务,用于将领域的业务逻辑、领域服务封装为用例,所以,我们把Service层改名为Application层。
  经过第四步的抽象,其架构图为:
  在这个架构图中,经典四层架构的四层都出现了,整个架构图长得跟六边形架构也很像。这是为什么呢?其实,不管是经典四层架构、还是六边形架构,亦或者整洁架构,都是对系统应用的描述,也许描述的侧重点不一样,但是描述的是同一个事物。既然描述的是同一个事物,长得像才是理所当然的。
  对于任何一个应用,都可以看成输入处理输出的过程。
  输入环节:通过某种协议对外暴露领域的能力,这些协议可能是REST、可能是RPC、可能是MQ的监听器,也可能是WebSocket,也可能是一些任务调度的T
  处理环节:处理环节是整个应用的核心,代表了应用具备的核心能力,是应用的价值所在,应用在这个环节执行业务逻辑。
  输出环节,业务逻辑执行完成之后将结果输出到外部。
  不管我们采用的什么架构,其描述的应用的核心都是这个过程。正如《金刚经》所言:一切有为法,如梦幻泡影,如露亦如电,应作如是观;凡有所相,皆是虚妄;若见诸相非相,即见如来。第五,完整的包结构
  将第四步中出现的包进行整理,并加入启动包,则得到如下完整的包结构。
  由于有很多的UserInterface,所以启动类应该存放在单独的模块中,又因为application这个名字被应用层占用了,所以将启动类所在的包命名为launcher。
  包结构如图所示:
  至此,DDD项目的整体结构基本讲完了。
投诉 评论 转载

收获满满的一天,新秀们快到马刺碗里来万众瞩目的选秀大会落下了帷幕,马刺管理层众望所归,终于没有浪费手里的3张首轮签选下3个2米以下的球员,也选到了大家心心念念的杰雷米索汗,补强了目前马刺急缺的四号位,这下众刺蜜可……发黄出油双眼无神,这些女星没了美颜滤镜,和普通人没区别!文娱情故纵编辑娱情故纵前言在人们的眼中基本上只要明星出镜时,那么必然是光鲜靓丽光彩夺目。但实际上别看他们看起来总是一副精致的样子,其实在没有了美颜滤镜这些加持……ThinkinginDDD(二)DDD的落地,主要有三个方面需要理清:第一,以何种应用架构进行落地;第二,核心组件及其生命周期,相互之间的交互逻辑;第三,不同限界上下文之间如何集成。本文将重点分析DDD……正式确定!山东男篮留下争议大外援,王晗要靠他冲击季后赛八强根据国内篮球记者宋翔报道,山东男篮已经对此前效力球队两个赛季的外援吉伦沃特使用外援优先续约权。山东男篮留下争议大外援吉伦沃特,这也意味着双方基本达成了签约协议,只是尚未完成签约……大屠刀终于还是挥向白酒国庆期间,海天酱油事件闹得人尽皆知,开盘没有悬念地逼近跌停,今天食品饮料今日也重挫4。7。白酒板块,五粮液跌6。1,贵州茅台跌4。62,泸州老窖跌8。82。下一个杀的白马……杨振宁翁帆为了我付出了太多时间,她十七年来都是早睡杨振宁和翁帆的爱情故事一直都在激励着我们,还记得当时杨老为了和翁帆告白,写了很深刻的诗句,上帝恩赐的最后礼物,给我的老灵魂,一个重回青春的欢喜。没有心机而又体贴人意,勇敢好奇而……挂牌近2年降价30万仍难出手!难卖的不只武汉,重点10城二手每经记者:甄素静每经编辑:魏文艺持续低迷的市场行情,让武汉当地房产经纪人陆豪的业务范围在一年内多次调整。起初陆豪主要做二手房交易,今年6月初开始主动为新楼盘带客户。……知名女星自曝患病已接受手术!这病严重会导致猝死,有这些症状的今天中午女艺人陈乔恩自曝患有严重的睡眠呼吸中止症并提醒网友注意此类健康问题话题登上热搜第一事情源于在某档综艺节目中,老公艾伦与陈乔恩视频时问道:那……绿茵江湖说魏群(下)(五)1995年11月18日,成都保卫战全兴主场迎战八一队的前一天,中国足球史上最著名的排队之夜,在蓉城上演。虽然已是冬季,梧桐更兼细雨,淅淅沥沥但成体中心的购票窗……区块链通证积分有哪些实用的商业场景?通证积分还可以这样玩?企业为什么要做通证?个体企业的发展往往在资金、资源、业务等层面陷入困境,资金的流动、人力物力等资源的汇集、用户的开拓及留存等问题,是一个企业或者项目发展的关键,也是企业家……渡十娘从谷爱凌的国籍之争看美国华裔是如何培养学霸运动员的冬奥会如火如荼,谷爱凌无疑是最闪亮的一颗明星。赛前中美两国的媒体和自媒体就围绕着她的国籍问题大做文章。昨天夺冠后又被问及这个问题,小姑娘倒是落落大方,回答也非常得体:我非常感谢……六尾solo赛全胜拿下!极限操作令明眸质疑你是不是开脚本了?相信很多的网友们对于高人气主播六尾一定非常熟悉,在平时直播的时候,六尾就经常会给粉丝们展示自己的操作,不得不说,六尾的守约确实是很厉害的,可以说六尾已经是国服公认的百里守约天花……
余承东传来消息,剧透鸿蒙3。0升级内容,首批推送机型也曝光了冬日幻想,畅玩新年!莱西启动冰雪嘉年华狂欢季官宣!勇士队正式拿出镇队之宝,库里剑指第四座总冠军奖杯特斯拉研发太阳能增程拖车增加续航,新能源板块大涨这么美的句子,不允许你们还没看过河南安阳华灯初上古城夜景绚丽如画喜讯!留洋锋霸确定火线驰援恒大,未来将解决郑智燃眉之急泰久不见!广西恢复出境旅游泰国首发团今日启程2149!米家消毒空气净化器开启众筹支持多重消毒灭菌释放边缘算力点燃智慧场景联想发布边缘服务器ThinkServ9位港星定居内地,有人月花10万租房,有人在一线城市有6套房努尔基奇我觉得驱逐追梦都已经过了,结果还禁赛?
如果玄宗不干涉,封常清,高仙芝,哥舒翰可以在潼关挡住安禄山吗王者荣耀芈月带什么召唤师技能伦敦奥运中国强!四核智能deovoV5强!热传聚热点网 魅力大波浪卷发打造浪漫夏季风海王实锤!克莱快攻撞翻女裁判,起身后相互示意太有爱了让我敬佩的一个人作文4篇新三板挂牌上市需要哪些中介机构热评聚热点网 有哪些完结的精品小说推荐?热闻聚热点网 柴里矿区学校致家长的一封信1000字如果泰森和李小龙过招,谁能笑到最后?年终奖,看上去是钱,实际上是人心陈古洲表弟诗来多感慨就韵寄酬

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找菏泽德阳山西湖州宝鸡上海茂名内江三亚信阳长春北海西安安徽黄石烟台沧州湛江肇庆鹤壁六安韶关成都钦州