当前位置: 首页 > news >正文

【领域驱动设计 学习目标及大纲】从CRUD到架构设计

从2018年至今,已工作了5年有余,回望这5年的工作历程,虽然一直在学习、一直在积累,但其实都在的层面上停留,也就是具体的技术点。这5年多的时间里其实也不是没有窥的想法:

  • 一次是2018年刚工作的时候,看着leader书桌的《领域驱动实践》,觉得自己行了,老写CRUD没意思,要搞搞,于是有了这篇【架构设计 领域驱动开发 一】三层VSDDD,当时甚至还只是在实习。只学了一点就没有再继续了,核心原因有两点:基础的尚不扎实;业务的输入太少,根本不懂的意义何在?翻看了半天不知所以然,人云亦云罢了。
  • 还有一次是在去年2022年的时候,那时其实已经积累了一套自己的完备知识体系了,也就是到位了;当然也知道自己的深浅,所以没有直接开始学习DDD,而是去将自己的术升级到最高阶,也就有了这篇【Java设计模式 学习目标及大纲】高质量代码的标准及实现路径,从面向对象思想、设计原则、设计模式、编码规范、代码重构这几个方面深化自己对于代码和设计思想的认知。

现如今经过一年多的业务工作磨炼,自身也开始负责一个独立的模块的开发,在开发过程中有一些偶发的困惑和经验,也就是有了一些现状的领悟和业务的输入了,此时有窥道正当时也。这个系列来自对极客时间的系列学习:手把手教你落地DDD

DDD的定义是什么

2003 年,Eric Evans 写了《领域驱动设计:软件核心复杂性应对之道》一书,正式提出了这种方法。领域驱动设计的英文是 Domain-Driven Design,所以简称 DDD。DDD 是一种开发复杂软件的系统化的方法学和思想,通俗的说就是提供了一套复杂软件开发的标准步骤

什么是方法学

方法学是研究和制定研究方法的学科,以面向对象方法学为例来说明:

  • 如果 Java 代码写得特别溜,可以说掌握了面向对象的编程方法
  • 如果熟悉面向对象的设计原则,掌握很多设计模式,那可以说懂面向对象的设计方法
  • 如果能为业务概念构建领域模型,那可以说懂了面向对象的分析方法

面向对象的分析、设计、编码三种方法融会贯通,成为一个有机的整体,这个叫面向对象的方法学,分析方法,或者说领域建模的方法,正是 DDD 的重点步骤

什么是系统化

系统化指的是,提供一套相对容易的步骤,能够使我们这些中等智商的人,也能做到原来高智商的人才能做到的事情,从而让你能够省出时间和脑力,来探索更复杂的问题。在软件开发领域,DDD 就是这样一套系统化的方法学。标准

DDD解决什么问题

DDD,即“领域驱动设计”,是软件工程中的一种软件开发方法学。它继承了面向对象和敏捷方法的精华,并提炼了一套更容易掌握的原则、模式和实践,特别适合复杂的企业应用的开发

  1. 通过领域建模,DDD可以帮助企业解决业务复杂、需求变化快、微服务架构拆分、系统重构等方面的问题。
  2. DDD强调从业务出发进行系统设计,利用领域建模将业务知识严格化和可视化,对齐业务和开发的理解,设计灵活、易扩展的系统,帮助业务需求走在正确的方向上
  3. DDD还提供了系统化的方法,帮助企业建立目标模型和设计目标架构,并结合演进式架构和代码重构等技术,解决系统架构和代码腐化的问题

DDD的来源是什么

DDD 是来自面向对象的方法学和敏捷软件开发。DDD 对它们进行了总结和提炼,使之更容易学习和实践,DDD 就是 OO Done right”。OO 就是面向对象,也就是说把面向对象做对了,就是 DDD。也可以反过来说,面向对象本来就是“领域驱动”的

传统面向对象方法的问题

早期面向对象的成功,主要是在几个特定的领域,比如计算机语言、图形用户界面、办公自动化软件等等,但在企业应用(银行的贷款系统、保险公司的理赔系统、电信公司的计费系统)方面还没有取得成功。那个时候的面向对象方法学还不能很好地应用于企业应用,大体上有以下几个原因

  • 第一个原因是,很多开发人员走了一条只重技术不重业务的弯路,企业应用是用来解决业务问题的,所以我们应该首先把业务研究清楚,再通过技术手段来实现。但很多开发人员把主要精力放到技术的研究上,比如语言、框架、工具等等。以为把技术学会了,自然就能把系统开发好。重技术、不重业务的思想造成了业务和技术人员之间难以相互理解,技术人员难以真正满足业务需求。开发人员重技术,不重业务
  • 第二个原因是,围绕业务进行开发的方法本身就不好学,领域建模是一种“手艺”。凡是手艺,都不是看看书、学学理论就能掌握的,而是要经过实践中的磨炼。领域建模实践起来有难度
  • 第三个原因是,早期面向对象方法学主要考虑的是建模技术,很少考虑协作问题,早期面向对象应用比较单一,协作少。企业应用则不同,多数都是团队作战。即使只有一线开发人员,也免不了和需求方打交道,早期面向对象方法学主要考虑的是建模技术,很少考虑协作问题
  • 最后一个原因是难以适应变化。企业应用的需求往往变化频繁,很多变化根本无法预料。传统的面向对象方法学也很少讨论怎样应对变化的需求,传统的面向对象方法学很少讨论怎样应对变化的需求

DDD如何应对企业应用

针对以上的四个原因问题,DDD的解决之道如下:

  • 把开发者从只重技术的弯路上拉回来:“领域”指的就是软件系统要解决的业务问题,也可以叫“业务领域”。用领域来驱动设计,就是说要从业务出发进行系统的设计。强调这个原则,就是希望把开发者从只重技术的弯路上拉回来
  • 总结出一套围绕领域建模进行软件开发的模式:要搞清业务,就要学会领域建模,为了简化这个过程,DDD 采用了“模式”(解决疑难问题应对的高招)的方法对面向对象方法学和敏捷软件开发方法进行了提炼,总结出了一套围绕领域建模进行软件开发的模式。其中最基础的模式包括:模型驱动设计,实体、值对象
  • 领域驱动设计非常强调业务人员和技术人员要一起协作进行领域建模,在这个过程中提炼领域知识。和协作密切相关的模式有通用语言、模型驱动设计、限界上下文
  • DDD 柔性设计,使得模型和系统可以随着需求的变化而演进,在软件设计中,不是一开始就把所有地方都设计得很灵活,而是先进行“足够的”和“整洁的”设计。随着业务变化,将变化频繁的部分重构得越来越灵活,而不常变化的部分则保持不变。也就是说,模型中的哪些部分需要设计得灵活,是自然演进形成的,这样就避免了“过度设计”。这个过程就是柔性设计。而这个重构的过程,也是不断加深领域知识理解的过程。

关于协作和演进,正是 DDD 的来源之一,敏捷软件开发所解决的重点问题

DDD为什么正当其时

DDD2003年就提了出来,为什么现在才火?

  1. 从整个业界来看,必要性还不够强
    • 在 DDD 刚出现的时候,很多企业软件还不太复杂,一些复杂的软件,变化也不像现在这样频繁。甚至还有一些企业,干脆每隔四五年把原来的系统推翻重建一次。
    • 当时一些新兴的产业,例如互联网,还处在跑马圈地、野蛮生长的阶段。这时关注的是系统快速上线,抢占市场,至于软件质量好不好,容不容易维护,暂时不是考虑的重点
  2. DDD 普及的一些前提条件也还没准备好:
    • 首先是敏捷软件开发刚刚出现不久,还不普及。如果没有迭代开发、持续重构、测试驱动、持续集成等敏捷实践的支持,构建良好的领域模型并在代码上落地是很困难的。
    • 其次是配套的开发框架还不成熟。那时 J2EE 还被认为是企业应用事实上的标准,而基于这种框架开发程序,是很难和 DDD 的领域模型相衔接的。2004 年,Spring 发布了 1.0 版,从技术上基本解决了 EJB 的问题,理论上可以比较好地支持 DDD。然而 Spring 的真正普及,还要假以时日

那么 DDD 为什么在这几年又火起来了呢

  1. 首先是,数字化时代的到来,使 DDD 变得非常有必要
    • 数字化时代,技术逐渐成为企业核心竞争力的主要因素,无论业务还是系统都变得更加复杂。因此,如何将业务和技术融为一体,就成了很多企业的主要问题,而这正是 DDD 的主要优势。
    • 行业竞争的加剧也要求系统具有更好的用户体验、更高的质量、更快地满足变化的需求。这些问题很难解决,必须引入系统化的方法
    • 云计算、微服务等新技术架构的产生,也需要方法学的支持
  2. DDD 普及的道路已经铺好,这项技术逐渐变得可行
    • 现在,敏捷软件开发已经普及迭代、演进、协作等思想已经深入人心DevOps 技术应用得也日益广泛。而且 Spring boot 等轻量级框架已经得到广泛使用。这些框架支持了领域模型与具体技术的关注点分离,使开发人员从技术细节中解放出来,将更多的精力投入到领域逻辑本身的分析和设计
    • 相关的架构实践也已经研究得比较透彻,像整洁架构、事件驱动架构以及 CQRS 等等,都有力地支持了 DDD 的落地实施。DDD 本身也在不断完善,比如补充了像领域事件等新的模式,出现了事件风暴等新的实践

总的来说,市场需要DDD,DDD所依赖的前提技术准备好了,思想也深入人心。

DDD学习的三个阶段

基于认知规律,学习分为三个阶段去执行,逐渐的从入门到高手

  • 迭代一:夯实基础:这个迭代旨在通过一个“需求-模型-代码”的闭环,初步形成对领域驱动设计(DDD)过程的完整感觉。
    • 首先学习事件风暴方法,梳理行为需求,并介绍统一语言**。
    • 其次将实操DDD的核心技能领域建模,引入实体、关联、模块等重要模式
    • 最后进行模型的实现,包括建立数据库、设计代码、编写代码
  • 迭代二:渐入佳境:学习一些高级的技能,
    • 首先从理论、模型和编码层面理解“聚合”。进一步提升领域建模能力,深化对分层架构和代码封装的理解。
    • 其次学习值对象,理解值对象的本质和优点,并解决值对象在建模和编程上的一些具体问题。
    • 最后,学习重要的建模技巧——泛化和限定,这是领域建模由初级走向中、高级的关键技能
  • 迭代三:掌握更高级的技能
    • 首先介绍“限界上下文”模式,通过分而治之来维护概念的一致性。在此基础上进一步学习微服务设计
    • 其次了解事件驱动架构CQRS 这两个重要的架构模式。讨论怎样为更加灵活多变的业务建模,并深化对高级泛化的理解。
    • 最后解决实际的落地问题,比如 DDD 切入点的选择,遗留系统的改造

整体的知识地图如下图所示
在这里插入图片描述

总结一下

DDD的重点是业务驱动的模型设计。它继承了面向对象和敏捷方法的精华,并提炼了一套更容易掌握的原则、模式和实践,特别适合复杂的企业应用的开发。早期因为市场大多数软件设计都在0-1的阶段,DDD的必要性不强且DDD所需的前提条件尚不具备。随着数字时代到来,企业应用业务逐步复杂,对技术架构的要求也逐步提高且经过发展DDD的前提条件逐步具备,所以DDD的使用正当其时。DDD的学习分三个阶段,首先是形成一个小闭环(业务事件风暴;领域建模;数据库设计、代码设计、代码编写),其次是运用一些最佳实践(聚合;值对象;泛化和限定),最后是一些高级用法(限界上下文、微服务架构;事件驱动架构、CQRS;落地问题)

相关文章:

【领域驱动设计 学习目标及大纲】从CRUD到架构设计

从2018年至今,已工作了5年有余,回望这5年的工作历程,虽然一直在学习、一直在积累,但其实都在术的层面上停留,也就是具体的技术点。这5年多的时间里其实也不是没有窥道的想法: 一次是2018年刚工作的时候&am…...

asla四大开源组件应用示例(alsa-lib、alsa-utils、alsa-tools、alsa-plugins)

文章目录 alsa设备文件/dev/snd//sys/class/sound/proc/asoundalsa-lib示例1alsa-utilsalsa-toolsalsa-plugins参考alsa设备文件 /dev/snd/ alsa设备文件目录位于,/dev/snd,如下所示 root@xboard:~#ls /dev/snd -l total 0 drwxr-xr-x 2 root root 60 Nov 6 2023 …...

文档理解的新时代:LayOutLM模型的全方位解读

一、引言 在现代文档处理和信息提取领域,机器学习模型的作用日益凸显。特别是在自然语言处理(NLP)技术快速发展的背景下,如何让机器更加精准地理解和处理复杂文档成为了一个挑战。文档不仅包含文本信息,还包括布局、图…...

【二叉树】Leetcode 637. 二叉树的层平均值

637.二叉树的层平均值 解题思路 根据层序遍历的模板进行修改;主要的不同是,不需要输出每一层所有节点值,只需要输出平均值,只需要定义一个double双精度浮点数储存每一层数的总和,输出时将总和除以层节点总数即为层平均…...

设计模式-15-Jdk源码中的设计模式

之前我们学习了一些设计模式,今天我们剖析Java JDK 源码中用到的几种常见的设计模式。 1-jdk之工厂模式 在前面讲到工厂模式的时候,大部分工厂类都是以Factory作为后缀来命名,并且工厂类主要负责创建对象这样一件事情。但在实际的项目开发中…...

Vue框架学习笔记——事件scroll和wheel的区别

文章目录 前文提要滚动条滚动事件 scroll鼠标滚动事件 wheel二者不同点 前文提要 本人仅做个人学习记录,如有错误,请多包涵 滚动条滚动事件 scroll scroll事件绑定html页面中的指定滚动条,无论你拖拽滚动条,选中滚动条之后按键盘…...

【LeetCode】每日一题 2023_11_29 无限集中的最小数字(哈希/堆)

文章目录 刷题前唠嗑题目:无限集中的最小数字题目描述代码与解题思路偷看大佬题解 结语 刷题前唠嗑 LeetCode?启动!!! 今天的题目也比较的简单,因为数据量不大,所以什么做法都能过的去 题目&a…...

C/C++ 常用的四种查找算法

在计算机科学中,搜索算法是一种用于在数据集合中查找特定元素的算法。C语言作为一种强大的编程语言,提供了多种搜索算法的实现方式。本文将介绍C语言中的四种常见搜索算法其中包括(线性查找,二分法查找,树结构查找&…...

Linux | Ubuntu设置 netstat(网络状态)

netstat命令用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。netstat是在内核中访问网络及相关信息的程序,它能提供TCP连接,TCP和UDP监听,进程内存管理的相关报告。 1.netstat的安装 搜…...

成为AI产品经理——模型构建流程(下)

目录 1.模型训练 2.模型验证 3.模型融合 4.模型部署 上节课我们讲了模型设计、特征工程,这节课我们来讲模型构建剩下的三个部分:模型训练、模型验证和模型融合。 1.模型训练 模型训练就是要不断地训练、验证、调优直至让模型达到最优。 那么怎么达…...

TCP Socket API 讲解,以及回显服务器客户端的实现

文章目录 TCPServerSocket APISocket API TCP 客户端服务器的实现 TCP ServerSocket API ServerSocket 是创建TCP服务端 Socket 的 API。 serverSocket构造方法: 方法签名方法说明ServerSocket(int port)创建一个服务端流套接字Socket,并绑定到指定端…...

2023年掌控安全学院CTF暖冬杯——数据流分析

前言:打工仔一枚,第一波上新的3题misc 做完了 再打ISCTF随便记录一下 PS:环境关了,题目描述忘记了,反正就是找flag。 筛选HTTP数据流 导出数据流慢慢看 ctrl F 搜flag 看到一条 有flag.txt 的数据 导出另存.zip 这里…...

UE4 基础篇十四:自定义插件

文末有视频地址和git地址 一、概念 虚幻里插件都是用C++写的,C++包括.h文件和.cpp文件,.h头文件通常包含函数类型和函数声明,cpp文件包含这些类型和函数的实现, 你为项目编写的所有代码文件都必须位于模块中,模块就是硬盘里的一个文件夹,包含名为“Build.cs”的C#文件…...

QT QGraphicsItem 图元覆盖导致鼠标点击事件不能传递到被覆盖图元

一、概述 在日常开发中,遇到这样一个问题,线图元和引脚图元重叠,导致点击引脚图元,没有进入引脚图元的鼠标点击事件中。 二、产生原因 如果您的 QGraphicsItem 上有一个图元覆盖了它,可能会导致鼠标事件无法正常触发…...

proto语法学习笔记

proto语法学习笔记 Protocol Buffers(Proto是由谷歌开发的一种数据序列化格式。 Proto 不是一种编程语言,而是一种接口描述语言(IDL),用于定义数据结构和消息格式。 它的设计目标是提供一种简单、高效、可扩展的方法来…...

python-nmap库使用教程(Nmap网络扫描器的Python接口)(功能:主机发现、端口扫描、操作系统识别等)

文章目录 Python-nmap库使用教程前置条件引入python-nmap创建Nmap扫描实例执行简单的主机发现(nmap -sn)示例,我有一台主机配置为不响应 ICMP 请求,但使用nmap -sn,仍然能够探测到设备: 端口扫描扫描特定端…...

什么是智慧工地?

一、什么是智慧工地? 工地本身不拥有智慧,工地的运作是依赖于人的智慧。工地信息化技术,能够减少对人的依赖,使工地拥有智慧。 智慧工地,就是立足于“智慧城市”和“互联网”,采用云计算、大数据和物联网等…...

【古月居《ros入门21讲》学习笔记】08_发布者Publisher的编程实现

目录 说明: 1. 话题模型 图示 说明 2. 实现过程(C) 创建功能包 创建发布者代码(C) 配置发布者代码编译规则 编译并运行 编译 运行 3. 实现过程(Python) 创建发布者代码(…...

沿着马可·波罗的足迹,看数字云南

刚入行的时候,有位前辈跟我说过一句话:去现场“要像外国人一样去看”,重新审视那些自己可能早已“熟视无睹”的事物。 前不久,我跟随“看见数字云南——云南数字经济媒体探营活动”,奔赴昆明、大理、西双版纳等地&…...

记录问题-使用@Validated报错Validation failed for argument [0]

类字段 NotNull(message "双坐标不能为空", groups {Insert.class, Update.class})private Integer yAxisType;接口 /*** 添加** return*/RequestMapping(value "/add", method RequestMethod.POST)public Result add(Validated(Insert.class) Request…...

JavaSec-RCE

简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性&#xff0c…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...