领域驱动架构

领域驱动架构什么是领域模型?为解决场景下的问题而形成的一套模型,然后使用这套模型来解决业务问题。根据重复劳动经验我们会形成一套模式。领域模型也一样会形成一套模式,他包括:实体、值对象、模块、领域服务领域模型是怎么更新到数据库的呢?使用资源库(repository)将领域模型更新到数据库。在一个一对多的实体,例如:用户组(Group)和用户(User),用户组内有N个用户,如果用户非常多,一次加载Group肯定会造成性能损失,这种问题怎么设计呢?如果不使用领域模型依靠经验你会想到拆分,现在你使用了领域

什么是领域模型?

为解决场景下的问题而形成的一套模型,然后使用这套模型来解决业务问题。 根据重复劳动经验我们会形成一套模式。领域模型也一样会形成一套模式,他包括:实体、值对象、模块、领域服务

领域模型是怎么更新到数据库的呢?

使用资源库(repository)将领域模型更新到数据库。 在一个一对多的实体,例如:用户组(Group)和用户(User),用户组内有N个用户, 如果用户非常多,一次加载Group肯定会造成性能损失,这种问题怎么设计呢? 如果不使用领域模型依靠经验你会想到拆分,现在你使用了领域模型想的方案也应该是拆分。 我看到有些人把repository注入到领域模型内,这种做法是错误的。

领域模型是否要引入一种架构模式?例如CQRS

首先我想说的是领域模型不需要引入架构模式。 领域模式是解决领域内的业务问题的,他不是解决架构问题,所以领域模型本身不需要引入架构。 当你使用领域模型的时候,领域层之上你可以使用架构,比如CQRSMVC等等。

下图为一种支持读写分离的演化:

领域驱动架构

写服务只有一个统一的Controller入口,通过URL路径与Body传入进入相应的service、方法与入参,然后利用反射定位到具体的Service的某个方法,逻辑处理完后再分发到单Dao,通过配置Vobj.xml映射到对应的表。这样的好处是新增业务只需要写Service与配置映射关系即可,不需要再新增Controller与Dao,Contoller变成了一层薄薄的接入层,大大简化了代码;读服务也有统一的Controller,通过Service分发到不同的DAO层实现,写自定义的SQL或利用ES存宽表来查。

领域驱动架构

领域驱动架构

与上面的单Dao实现类似,建立统一的Controller与通用的仓库与工厂,利用数据库第三范式实现服务内数据补填,利用服务调用实现跨服务数据补填。

整洁架构

整洁架构的核心思想是通过适配器层解耦业务层与技术框架层代码,使得业务代码与技术框架可以各自升级迭代,互不影响。我们都知道,技术架构一直以来都在不断变化,对项目的技术架构调整成本是非常高的,如何降低这种成本?

这时候整洁架构就派上用场了。

领域驱动架构

如上图所示,中间的Entities与Use Cases属于业务领域层,Entities表示业务领域模型的核心业务,Use Cases表示与用户交互的Service;最外层技术框架层是各种技术实现,与业务无关的一层;那业务与技术怎么进行关联呢?通过中间绿色的接口适配器层实现。适配器层分离了技术实现与业务逻辑。

下图为整洁架构的一种落地方案。

领域驱动架构

领域驱动架构

需求用例:

使用传统项目来开发整个需求

首先来看下我们的项目结构:

领域驱动架构

 这个项目结构大家已经非常熟悉了,就是我们传统的分层方式。 我们通常会把业务逻辑写在service里面,如下:

领域驱动架构

整个功能我们已经开发完了,是不是看着非常简单。 我们来看changePassword方法,我们通过repository根据用户名获得到用户, 然后调用authenticate方法进行认证,认证通过后修改密码(user.setPassword())。 是不是看上去没有任何毛病,而且程序还运行的非常成功。嗯,确实是。 但是在这种编程模式里我们更多的是从数据库的模式来开发的,因为User只是封装了静态数据。 然后在service中来完成修改密码这个逻辑,这种操作更像是过程化编程

我们应该从面向对象的角度来思考问题。 一提到对象你首先想到的是什么?继承?封装?多态?还有吗? 我再添一条类是一组相关的属性和行为的集合

既然我提到了属性和行为,那我们重新思考下修改密码这个用例: 首先passwordUser类上的一个属性,对于修改密码我们应该是调用User对象上的changePassword方法, 然后由changePassword来完成修改password属性,这就是封装。

接下来我们使用领域模型再来完成上面用例的业务。

使用DDD来开发整个需求

首先我们也是来看一下DDD的项目结构:

领域驱动架构

当你看到这个项目结构的时候,你可能心生疑惑:“怎么没有service, repository这样的包呢?”

我来告诉你,IDDD推荐我们使用应用层、领域层和基础设施层来做分层。 对于这种分包方式是《实现领域驱动设计》这本书比较推荐的。所以这个项目我们以这种方式来组织我们的代码。

接下来我们来看看应用层服务和领域模型:

领域驱动架构

 领域驱动架构

再来看UserService上的changePassword方法,我们还是通过authenticate获得用户, 然后又调用了用户的changePassword来修改密码。

但是你会发现我们并没有把密码加密这个交由User来完成,这是为什么呢?

因为加密不是User的职责。就像authenticate一样,你自己不可能认证自己, 就像你不借助镜子永远不会看清你的脸蛋。就像你会问别人我今天漂不漂亮,而不会自欺欺人的告诉自己我很漂亮。

通过将changePassword交由User,你会发现你的业务很清晰了。 因为你对号入座将原本由用户该做的事情又还给了用户。

最后推荐一般书:《复杂软件设计之道:领域驱动设计全面解析与实战》帮助你更好的了解领取驱动设计的思想和实战。

今天的文章领域驱动架构分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/24792.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注