实现DDD领域驱动设计: Part 1

原文链接: https://dev.to/salah856/implementing-domain-driven-design-part-i-5a72

简单的代码!

踢足球很简单,难的是踢简单的足球。— 克鲁伊夫

如果我们将这句话用到编程上,我们可以说;

写代码很简单,难的是写简单的代码。

什么是领域驱动设计?

领域驱动设计(DDD)是一种软件开发方法,通过将实现结合不断发展的模型来满足复杂的需求。

DDD适用于复杂的领域和大规模的应用程序,而不是简单的CRUD应用程序。

它专注于核心领域逻辑,而不是基础设施细节。它有助于构建灵活、模块化和可维护的代码库。

OOP & SOLID

DDD的实现高度依赖于面向对象编程(OOP)和SOLID原则。

实际上,它实现并扩展了这些原则。因此,对OOP和SOLID的良好理解对你实现DDD有很大帮助。

DDD分层和整洁架构

基于领域驱动的解决方案有四个基本分层。

33de3e641425dc4b50a1122494c53930.png

业务逻辑分为两层,领域层和应用层,它们包含不同类型的业务逻辑;

  • 领域层实现领域/系统的核心、独立于用例的业务逻辑。

  • 应用层基于领域实现应用的用例。可以将用例视为用户界面 (UI) 上的用户交互。

  • 表示层包含应用程序的UI元素(页面、组件)。

  • 基础设施层通过实现对第三方库和系统的抽象和集成来支持其他层。

相同的分层可以如下图所示,称为整洁架构,有时也称为洋葱架构:

39e22544c18694701bbcee91c3915a2c.png

核心构建块

DDD主要关注领域层和应用层,而忽略了表示层和基础设施。它们被视为细节,业务层不应依赖它们。

这并不意味着表示层和基础设施层不重要。

它们非常重要。UI框架和数据库提供商有自己的规则和最佳实践,你需要了解和应用它们。但是,这些不在DDD的主题中。

本节介绍领域层和应用层的基本构建块。

领域层构建块

  • 实体Entity:实体是具有自己的属性(状态、数据)和实现在这些属性上执行的业务逻辑的方法的对象。实体由其唯一标识符 (Id) 表示。具有不同Id的两个实体对象被视为不同的实体。

  • 值对象Value Object:值对象是另一种领域对象,由其属性而不是唯一的Id进行标识。这意味着具有相同属性的两个值对象被视为同一个对象。值对象通常被实现为不可变的,并且大多比实体简单得多。

  • 聚合Aggregate和聚合根Aggregate Root:聚合是由聚合根对象绑定在一起的一组对象(实体和值对象)。聚合根是具有一些额外职责的特定类型的实体。

  • 仓储Repository(接口):仓储是一个类似于接口的集合,领域和应用层使用它来访问数据持久性系统(数据库)。它对业务代码隐藏了DBMS的复杂性。领域层包含存储库的接口。

  • 领域服务Domain Service:领域服务是实现领域核心业务规则的无状态服务。它是对于实现依赖于多个聚合(实体)类型或一些外部服务的领域逻辑很有用。

  • 规范Specification:规范用于为实体和其他业务对象定义命名的、可重用的和可组合的过滤器。

  • 领域事件Domain Event:领域事件是一种在发生领域特定事件时以松散耦合的方式通知其他服务的方式。

应用层构建块

  • 应用服务Application Service:应用服务是无状态的实现应用用例的服务。应用服务通常会获取并返回DTO。它由表示层使用。它使用和协调领域对象来实现用例。用例通常被视为一个工作单元。

  • 数据传输对象(DTO):DTO是一个没有任何业务逻辑的简单对象,用于在应用层和表示层之间传输状态(数据)。

  • 工作单元(UOW):工作单元是应作为事务单元完成的原子工作。UOW中的所有操作都应该在成功时提交或在失败时回滚。

实现: 整体结构

.NET解决方案

下图显示了使用ABP的应用程序启动模板创建的Visual Studio解决方案:

34d4a88e145bf3f252f8684ff2aab0b7.png

领域层

领域层分为两个项目;

  • IssueTracking.Domain,是基本的领域层,包含之前介绍的所有构建块(实体、值对象、领域服务、规范、仓储库接口等)。

  • IssueTracking.Domain.Shared,是一个精简项目,其中包含一些属于领域层但与所有其他层共享的类型。例如,它可能包含一些与领域对象相关的常量和枚举,但需要被其他层重用。

应用层

应用层也分为两个项目;

  • IssueTracking.Application.Contracts,包含应用服务接口和这些接口使用的DTO。该项目可以由客户端应用程序(包括 UI)共享。

  • IssueTracking.Application,是实现Contracts项目中定义的接口的基本应用层。

表示层

  • IssueTracking.Web,是此示例的ASP.NET Core MVC/Razor Pages应用程序。这是为应用程序和API提供服务的唯一可执行应用程序。

远程服务层

  • IssueTracking.HttpApi,包含解决方案定义的HTTP API。它通常包含MVC控制器和相关模型(如果可用)。因此,在此项目中编写HTTP API。

  • IssueTracking.HttpApi.Client,一个需要使用你的HTTP API的C#应用程序。一旦客户端应用程序引用了这个项目,它就可以直接注入和使用应用程序服务。这可以在ABP框架的动态C#客户端API代理系统的帮助下实现。

基础设施层

在DDD实现中,你可能有一个基础设施项目来实现所有的抽象和集成,或者可能对每个依赖项都有不同的项目。

我们建议采取平衡的方法;为主要基础设施依赖项(如 Entity Framework Core)创建单独的项目,为其他基础设施创建一个通用基础设施项目。

ABP的启动解决方案有两个用于Entity Framework Core集成的项目;

  • IssueTracking.EntityFrameworkCore,是EF Core必不可少的集成包。应用程序的DbContext、数据库映射、存储库的实现以及其他与EF Core相关的内容都位于此处。

  • IssueTracking.EntityFrameworkCore.DbMigrations,是一个用于管理Code First数据库迁移的特殊项目。这个项目中有一个单独的DbContext来跟踪迁移。除了需要创建新的数据库迁移或添加具有一些数据库表并且需要创建新的数据库迁移的应用程序模块外,通常不会过多地接触这个项目。

还有一个项目,IssueTracking.DbMigrator,它是一个简单的控制台应用程序,它迁移数据库模式并在执行它时初始种子数据。

它是一个有用的实用程序,你可以在开发和生产环境中使用它。

解决方案中项目的依赖关系

a8ac0078463713aea9a95592a7a108fd.png

基于DDD的应用程序执行流程

下图显示了基于DDD模式开发的Web应用程序的典型请求流。

543c773112cc242c6c5303a9c6439557.png

  • 请求通常从用户界面(一个用例)上的用户交互开始,该交互导致对服务器的HTTP请求。

  • 表示层(或分布式服务层)中的MVC控制器或Razor页面处理程序处理请求,并可以在此阶段执行一些横切关注点(授权、验证、异常处理等)。控制器/页面注入相关的应用程序服务接口并通过发送和接收DTO调用其方法。

  • 应用服务使用领域对象(实体、存储库接口、领域服务等)来实现用例。应用层实现了一些横切关注点(授权、验证等)。应用程序服务方法应该是一个工作单元。这意味着它应该是原子的。

大多数横切关注点都是由ABP框架自动且按惯例实现的,你通常不需要为它们编写代码。

数据库提供者/ORM 独立性

领域层和应用层应该与ORM/数据库提供者无关。

它们应该只依赖于Repository接口,并且Repository接口不使用任何ORM特定对象。

使用这个原则的主要原因如下;

  1. 使你的领域/应用程序基础架构独立,因为基础架构将来可能会发生变化,或者你以后可能需要支持第二种数据库类型。

  2. 使你的领域/应用程序专注于业务。通过隐藏仓储后面的基础设施细节来编写代码。

  3. 为了使你的自动化测试更容易,因为你可以在这种情况下模拟存储库。

如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/292635.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

XE5 Android 开发实现手机打电话和发短信 [转]

其实都可以通过intent和URI调用系统功能.Windows程序员可以理解成是ShellExecute.这个是万金油.可以有调用各种功能.后面会介绍. 1.短信息.很简单 方法a.不使用Intent而是直接发短信. smsManager对应的Delphi代码应该是: usesAndroidapi.JNI.JavaTypes,Androidapi.JNI.Telephon…

安装程序无法创建新的系统分区也无法定位现有分区的解决方法

2019独角兽企业重金招聘Python工程师标准>>> 在安装Windows7时,想必有很多人都安碰到这样的情况吧!在安装界面里选择安装时,却出现“安装程序无法创建新的系统分区,也无法定位现有系统分区” 网上提供的另外解决方法大全&#xff…

python多线程读取数据库数据_Python基于多线程操作数据库相关知识点详解

Python基于多线程操作数据库相关问题分析 本文实例分析了Python多线程操作数据库相关问题。分享给大家供大家参考,具体如下: python多线程并发操作数据库,会存在链接数据库超时、数据库连接丢失、数据库操作超时等问题。 解决方法&#xff1a…

IDA64 Fatal error before kernel init

http://www.tuicool.com/articles/7FZVZna 第一次看到这个错误还以为是修改文件导致的,但是觉得又不大像,因为在Win7底下是完全正常的。搜索了一下才发现是由于插件导致的: NOTE3: You get a “Fatal error before kernel init” when trying…

Android安全与逆向之在ubuntu上面搭建NDK环境

1、下载Android NDK自解压包, 官方地址:https://developer.android.com/ndk/downloads/index.html#download下载:$ wget -c http://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin 2、解压, 将Android NDK压缩包…

和我一起来分析某药品仓储管理系统 卡死现象

一:背景 1. 讲故事这个月初,有位朋友wx上找到我,说他的api过一段时间后,就会出现只有请求,没有响应的情况,截图如下:从朋友的描述中看样子程序是被什么东西卡住了,这种卡死的问题解决…

如何定位Source Generators性能问题

前言在以前的文章中,我们介绍过如何调试Source Generators。但是当实现较为复杂时,我们需要能够快速地分析Source Generators性能的方法。默认情况下,使用VS 2019自带的“性能探查器”不能分析Source Generators项目,因为它是类库…

什么是域(domain)

在今天很多人都有意识或无意识的跟域这个东西打过交道。如果你在公司里使用电脑,并且你的电脑接入了公司的局域网,那你的电脑很可能就在一个域中。如何查看你的电脑是否连接到一个域中,以Windows为例,右击我的电脑 –>属性&…

四舍五入运算

为什么80%的码农都做不了架构师?>>> 请用户输入1个实数(浮点型),请编写算法对这个实数进行四舍五入到个位的运算. 例如 12.56经过四舍五入运算得到13. 而12.45经过四舍五入运算得到12 代码如下地址: http://git.oschina.net/touch1D/qf17j3eughwdp8zxi…

python 新建html_Python学习第226课——html中创建按钮

前面我们学习了一些常见的表单元素,表单就是用来收集用户的信息的,比如调查问卷、用户登录网站的页面等这类的网页,里面都要用到表单元素,当用户在前端页面上填入账号、密码、或者调查问卷的答案等等信息之后,就需要提…

WPF 实现图片切成九宫格控件~

WPF开发者QQ群: 340500857由于微信群人数太多入群请添加小编微信号yanjinhuawechat 或 W_Feng_aiQ 邀请入群需备注WPF开发者 PS:有更好的方式欢迎推荐。接着上一篇倒计时控件01—代码如下一、创建 CropControl.cs代码如下。(修改RowColumn “…

GCT之数学公式(三角函数)

转载于:https://www.cnblogs.com/jyh317/p/3386598.html

Android安全与逆向之Java虚拟机和Dalvik虚拟机的区别

Google于2007年底正式发布了Android SDK, 作为 Android系统的重要特性,Dalvik虚拟机也第一次进入了人们的视野。它对内存的高效使用,和在低速CPU上表现出的高性能,确实令人刮目相看。 依赖于底层Posix兼容的操作系统,它可以简单的…

软件与硬件我该选哪个_MacBook Air 和 MacBook Pro 该选哪个……?

一个多月前,Apple 发布了 2019 款 MacBook Air 和 MacBook Pro,经过这一次的更新之后,MacBook 产品线总算变得更加清晰了,同时也减少了之前存在的价格和定位产生冲突的现象。不过从购买决策来看,我发现还是有些问题难倒…

只要300页!火遍全网的NET6+linux知识手册!拿走不谢!

这是微软公司基于最新的.net 6编写,循序渐进地对.net6/C#10进行讲解。对于零基础可以作为.net的快速入门教材,对于高级程序员而言,这也是你的进阶之路!NO.1资料介绍该手册,全面的介绍.net6和c#的新特性,看完这个资料&a…

Linux0.11内核剖析--内核体系结构

一个完整可用的操作系统主要由 4 部分组成:硬件、操作系统内核、操作系统服务和用户应用程序,如下图所示: 用户应用程序是指那些字处理程序、 Internet 浏览器程序或用户自行编制的各种应用程序; 操作系统服务程序是指那些向用户所…