最新领域驱动架构(DDD)建模中的模型到底是什么?,廖师兄springcloud视频

最后

ActiveMQ消息中间件面试专题

  • 什么是ActiveMQ?
  • ActiveMQ服务器宕机怎么办?
  • 丢消息怎么办?
  • 持久化消息非常慢怎么办?
  • 消息的不均匀消费怎么办?
  • 死信队列怎么办?
  • ActiveMQ中的消息重发时间间隔和重发次数吗?

ActiveMQ消息中间件面试专题解析拓展:

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM


redis面试专题及答案

  • 支持一致性哈希的客户端有哪些?
  • Redis与其他key-value存储有什么不同?
  • Redis的内存占用情况怎么样?
  • 都有哪些办法可以降低Redis的内存使用情况呢?
  • 查看Redis使用情况及状态信息用什么命令?
  • Redis的内存用完了会发生什么?
  • Redis是单线程的,如何提高多核CPU的利用率?

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM


Spring面试专题及答案

  • 谈谈你对 Spring 的理解
  • Spring 有哪些优点?
  • Spring 中的设计模式
  • 怎样开启注解装配以及常用注解
  • 简单介绍下 Spring bean 的生命周期

Spring面试答案解析拓展

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM


高并发多线程面试专题

  • 现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行?
  • Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优势?如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。
  • Java 中 wait 和 sleep 方法有什么区别?
  • 如何在 Java 中实现一个阻塞队列?
  • 如何在 Java 中编写代码解决生产者消费者问题?
  • 写一段死锁代码。你在 Java 中如何解决死锁?

高并发多线程面试解析与拓展

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM


jvm面试专题与解析

  • JVM 由哪些部分组成?
  • JVM 内存划分?
  • Java 的内存模型?
  • 引用的分类?
  • GC什么时候开始?

JVM面试专题解析与拓展!

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 订单=客户+商品信息

  • 维修单=客户+商品信息+维修信息

  • 客户=名字+电话

这里,维修单模型里面似乎包含了一个完整的订单(客户+商品信息),为什么不直接复用订单呢?也许是因为维修部门也负责别的地方购买的商品。另外,客户的名字和电话更新之后,是不是要直接修改已经完成的订单和维修单呢?值得商椎,已经完成的信息不应该有意料之外的变化。还有,如果客户是一个单独的模型,那么背后的团队会是怎么样呢?需要仔细考虑。

当数据模型可以完全覆盖业务需要,建模也就初步完成了。

那么,为什么要建模?第一,要把心智模型提取出来,显性化,让不同的人对业务的理解达成一致;第二,要归类复用,避免重复的工作,让人可以关注更高层面的事务。

如前面所示,即便是建立简单的模型,我们也需要诸多考虑。把这些需要考虑的点体系化,就引出了下一个问题:怎么建模才合理?

怎么建模才合理

判断模型好坏的重要依据是它的使用效率(扩展度、灵活度、与组织的对应度),所以建模的合理性也围绕这个来展开。

为了形成高扩展度、高灵活度并且顺应康威定律的模型,Eric Evans 汇总并命名了DDD这种方法论。它的独特之处,是它认可了“人”这种生物在做抽象过程中的一些必然缺憾,并且提出了一些解决方案。

首先,它明确指出了“自然语言”这个工具的不精确性。其次,它明确指出了人在设计和实现上的矛盾性,即:人类的预测能力很差,所以我们拥抱变化;但同时,我们不能纯寄希望于误打误撞地演化出一个好结果,应该提前深思熟虑地做好设计,再辅之以小的改进。

语言的不精确性,可以用“普通话”(Ubiquitous Language)来解决,即大家在讨论任何东西之前先规范语言,统一词汇的定义。兼顾稳固和灵活的设计,则由良好的分层来做到。

DDD把模型分成四层。

·Ul层,负责界面展示。

·应用层(Application Layer),负责业务流程。

·领域层(Domain Layer),负责领域逻辑。

·基建层(Infrastructure Layer),负责提供基建。

分类的依据是:越往上,预期变动越频察;越往下,预期变动越少。

对于程序员来说,UI和基建应该很容易分清,一个只管展示,一个只管提供持续储存、网络传输等等基础设施,都没有“业务”的参与。容易混淆的是应用层和领域层,在这两层中存在的,就是应用模型和领域模型。

这就引出了下一个问题:到底什么是领域模型?

什么是“领域”模型

按DDD的定义,领域模型应该捕捉“业务规则”或者“领域逻辑"(business rules/domain logic),而应用模型则捕捉“应用逻辑”(application logic)。

模型属于哪一层,有个粗略的判断方式。如果是一个实体(entity)和针对实体的增删改查,就属于领域层;如果是一个场景,比如出现在UI菜单上的选项,就属于应用层。

比如:账单,用户,编辑商品,编辑库存,这些是领域层;“购买商品”,则是应用层。

前者是针对实体的操作。每一个实体都只有增删改查这样的操作。与之相反的是,要完整实现“购买商品”这个场景,也许需要检查库存、创建订单、创建交易等多个操作。

这样看来,领域模型就像是数据库的表。不过,除了字段定义之外,领域模型还需要有领域逻辑。关系型数据库通常可以部分实现领域逻辑,比如使用外键、自增ID等等,但是更为复杂的领域逻辑则需要用代码来实现。比如,在创建订单的时候,需要扣除相应数量的库存;当订单失效,则需要恢复库存。

我们可以从两个方面理解领域逻辑。

第一,领域逻辑就是显性的专业知识,是相对容易理解和学习的部分。买了东西要给钱,出了货要扣库存,飞机来了要腾跑道,炮弹来了要拦截,这些都是专业知识中符合逻辑,可以很容易地推导和学习。与之相对的是隐性的专业知识,或者Martin Fowler 所说的“业务非逻辑"(business illogic),指的是逻辑很难推论的软知识,与人相关的部分,与不可抗拒的、稀奇古怪的意外情况相关的部分。

第二,领域逻辑是提纯、通用的规则。不管是买手机、买房、买汽车,都会有创建订单、创建交易这样的零售领域模型,它是高度提纯、通用的。如果我们需要去修改领域模型,说明我们已经进入了另一个领域。此外,规则的存在是为了维护某个事物,这个事物,就是领域模型的正确、完整性。对领域模型的正常操作,总会给我们一个“合规”的领域。

不管我们怎么去玩弄订单、交易、商品模型,增删改查,乱搞一通,最后出来的结果都应该符合规则。创建订单的时候,订单模型会尝试减库存,成功,则创建,失败,则不允许创建,如此云云。

最后出来的结果不会有逻辑问题,比如订单上的商品不存在,或者交易对应的订单不存在。

当然,领域模型只管“合规”,但不管“合理”。大型超市里,一位收银员决定把所有货品下架,这是否合理?这个不属于领域模型关心的范围,领域模型只知道,要把货物库存的位置从货架转移到仓库,目标仓库必须有能存放这个货物的空位,转移完毕时从货架的可用空间中减去货物的大小。至于谁做,为什么做,能不能做,这么做合不合理,(通常)不在领域层的关心范围,而是放到应用层去做。

在前面的例子中,如果一个客户在黑名单中,不允许购买,那么这个检查,通常是在应用层去检查。这样,我们就可以很容易地复用领域模型或者调整应用规则,而不至于把易变的应用规则混到稳定的业务规则里去。

模型的设计和实现

那么,DDD的模型属于业务描述还是代码、数据库定义?作者想表达的意思很明确,二者都是。好的业务描述应该能非常好地对应到代码,代码也应该以最清晰地方式来呈现业务描述。当然,转换和适配肯定不可少,毕竟有先例摆在那。想要达到设计即代码的UML,尸体都还是温的。

设计和实现的最佳契合点,其实就在“界面”之中。“界面”这个名字本身已经体现了这层意思。所以,建好的模型,和暴露出来的界面、接口,应该有相当高(或者完全一致)的对应关系。这个界面,可能是一个类的公开成员函数,也可能是一个微服务上暴露出来的RESTful接口,或者是一个公开的普通WebAPl,都没有差,只要和设计符合就行。

最后,总结起来,就是:

  • DDD把业务分成UI、应用、领域、基建四层,其核心是高度提纯、通用、少变化的领域层,是谓“领域驱动";

  • 领域层中包含领域模型,捕捉领域逻辑,暴露出接口用于操作领域模型,这些接口提供的操作可以确保领域是自治的;

  • 领域模型既是业务描述,又是代码实现的结构设计,二者的结合点在于公开出来的界面、接口。

领域模型的特点


总结一下,领域模型具有如下的特点:

  • 领域模型是业务概念的可视化描述,是需求分析的产物

  • 领域模型用于指导程序设计,但领域模型与实现方式无关,领域建模时不应该考虑如何实现

  • 领域模型需要同项目所有成员(客户、项目经理、开发、测试…)达成共识

如何画领域模型


(1)找出用例模型中的名词,

(2)然后识别这些名词本身的相关信息,

(3)以及名词之间的相互关联关系,

(4)用UML画出领域模型。

第一步:找出用例模型中的名词

原有用例如下,用蓝色加黑标出名词(重复的就不标了):

1)顾客携带商品到收银台;

2)收银员扫描商品条形码;

3)系统根据条形码获取并显示商品信息;

4)收银员重复2~3步,直到所有商品扫描完毕;

5)系统计算商品总额;

。。。。。。。。。。。。。。。。。。。。

n)系统打出商品清单,完成交易。

这个用例中的名词有“顾客”、“商品”、“收银台”、“收银员”、“商品条形码”、“系统”、“商品信息”、“商品总额”、“商品清单”、“交易”。稍加整理:

1)“顾客”、“收银员”是系统的外部对象,不需要我们进行设计,但这些对象要和系统进行交互;

2)“商品”、“商品条形码”、“商品信息”、“商品总额”、“商品清单”、“交易”是领域对象,但“商品条形码”、“商品信息”可以算作“商品”的属性、“商品总额”可以算作“交易”的属性,最后从这个用例总结出来的领域对象有“商品”、“商品清单”、“交易”三个。

总结

总体来说,如果你想转行从事程序员的工作,Java开发一定可以作为你的第一选择。但是不管你选择什么编程语言,提升自己的硬件实力才是拿高薪的唯一手段。

如果你以这份学习路线来学习,你会有一个比较系统化的知识网络,也不至于把知识学习得很零散。我个人是完全不建议刚开始就看《Java编程思想》、《Java核心技术》这些书籍,看完你肯定会放弃学习。建议可以看一些视频来学习,当自己能上手再买这些书看又是非常有收获的事了。

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

以看一些视频来学习,当自己能上手再买这些书看又是非常有收获的事了。

[外链图片转存中…(img-AoX6fSgV-1715686993917)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值