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

DDD该怎么去落地实现(1)关键是“关系”

DDD落地的关键是“关系”

这些年,我认为DDD走到了一个死胡同里了,因为落地实现过于困难。很多团队在经过一段时间的学习,清楚理解了DDD那些晦涩的概念,根据业务绘制出领域模型,这都不困难。但绘制领域模型不是我们最终的目的,最终的目的是基于领域模型,设计开发出业务系统。这时,很多团队就犯难了。这里面的关键问题就在于,采用DDD传统的做法,软件开发过于复杂,使得开发工作量不仅没有降低,甚至更高了。编写代码的增大,不仅使第一次的开发工作量增加,更要命的是日后变更维护的工作量增大,使得日后的维护变得困难。

采用了DDD,应当使得我们的开发变得简单,代码变得清爽,而不是代码变得臃肿。因此,我认为DDD也需要适当地变革,通过将一些通用的代码下沉底层平台,简化软件的开发。只有开发变得简单了,开发工作量减少了,DDD才能真正推行下去。我将通过一系列的文章,探讨一下DDD如何简化,我的设计思路,希望给大家带来帮助。

今天,首先谈谈模型对象间的关系,以及如何落地设计编码。在DDD的软件开发模式中,其实划分为两个阶段:基于业务的领域建模、基于领域模型的编码实现。在第一个阶段中,DDD要求我们首先深入地理解需求背后的业务,深入地掌握业务领域知识,然后将我们对业务的理解形成领域模型。在这个阶段中,我们会先划分限界上下文,将纷繁复杂的业务划分成一个一个较小的区域。然后,基于每个限界上下文的业务进行领域建模,形成如下的领域模型:

注意,在这个领域模型中,包含许多领域对象,如订单、用户、地址。每个领域对象包含各种的属性和方法,以及相互的关系。譬如,一个订单对应一个用户,但一个用户可以有多个订单,因此从订单到用户是一个“多对一”关系,有一个从订单多用户的箭头。这个箭头什么意思呢?它代表在订单对象中有一个属性是“用户”,并且是一个指针指向用户对象,落地到程序就是这样写的:

@Data
@EqualsAndHashCode(callSuper = true)
public class Order extends Entity<Long> {private Long id;private Long customerId;private Long addressId;private Double amount;private Date orderTime;private Date modifyTime;private String status;private Customer customer;private Address address;private Payment payment;private List<OrderItem> orderItems;...
}

在这个模型中,订单对象有4个箭头,指向“用户”、“用户地址”、“支付”和“订单明细”。这个箭头称为“导航”,它代表对象和对象之间的关系。然而,这些关系的类型是不一样的,从订单到用户和用户地址是“多对一”关系;从订单到支付是“一对一”关系;从订单到订单明细是“一对多”关系。

但现在的问题就在于,“一对一”和“多对一”关系,在这段代码中都是一个指针变量,我们无法从代码上区分它们到底是什么类型。同样,“一对多”关系在代码上是一个集合指针,如这里的订单,我们同样无法区分它到底是“一对多”还是“多对多”关系。也就是说,DDD要求我们将领域模型的原貌直接映射成代码实现。但真正代码实现时,仅仅写一个领域对象不能把领域对象间的关系描述清楚。所以,我们必须要在领域对象的基础上进行补充说明,来说明对象间的关系。我们通过一个DSL来描述。

DSL(Domain Specific Language,领域特定语言)是针对某个特定领域的计算机程序设计语言。在DDD中的DSL就是领域驱动设计这个特定领域的计算机设计语言,我们可以用xml、yaml、json等任何格式的文档来表达,但它表达的是领域驱动中的“对象”、“对象的属性”、“对象间的关系”,以及如何与数据库映射等相关的内容。

<do class="com.edev.trade.order.entity.Order" tableName="t_order"><property name="id" column="id" isPrimaryKey="true"/><property name="customerId" column="customer_id"/><property name="addressId" column="address_id"/><property name="amount" column="amount"/><property name="orderTime" column="order_time"/><property name="modifyTime" column="modify_time"/><property name="status" column="status"/><join name="customer" joinKey="customerId" joinType="manyToOne"class="com.edev.trade.order.entity.Customer"/><join name="address" joinKey="addressId" joinType="manyToOne"class="com.edev.trade.order.entity.Address"/><join name="payment" joinType="oneToOne" isAggregation="true"class="com.edev.trade.order.entity.Payment"/><join name="orderItems" joinKey="orderId" joinType="oneToMany"isAggregation="true" class="com.edev.trade.order.entity.OrderItem"/>
</do>

这里可以看到,通过一个xml文件,描述了订单对象的所有补充信息。在这里有订单对象的所有属性,以及它的所有关系。在这些关系中,不仅描述了每个关系的类型,还描述了它的关联属性,以及是否是聚合关系。与此同时,在这个DSL中还描述了订单对象对应的数据库表,以及每个字段对应的订单对象中的属性。有了这个DSL,才真正将领域模型的原貌映射到设计编码中。

除了设计编码,领域模型还要落地到数据库设计中。因此,DDD落地实现的关键是正确地识别领域对象间的“关系”。只有在领域建模的过程中正确地识别这些关系,才能在后面的程序编码与数据库设计中,做出正确的设计。这里的关系有“一对一”、“多对一”、“一对多”、“多对多”以及继承关系,我们一个一个来讨论吧。

首先是一对一关系。订单与它的支付就是一对“一对一”关系,一个订单只能有一个支付,而每个支付都要对应一个订单。这里其实有2个约束:每个支付必须对应一个订单,在数据库中通过一个外键来表示;一个订单只能有一个支付,这是一个唯一性约束,因此将刚才的那个外键变为了支付表的主键。最后的效果就是,订单表的主键变成了支付表的主键。通过这个主键,每条支付记录都要对应一个订单,但有些订单可能在支付表中没有记录。

值得注意的是,一对一关系的双方,到底谁指向谁,其实没有定理,必须基于相应的功能来决策。譬如,用户与会员也是一对一关系,然而应当谁指向谁呢?看后面的功能如何设计。如果将用户与会员当成彼此独立的模块,用户查询不显示会员,而会员查询却要显示对应用户,则会员指向用户;相反,如果将会员作为用户的子功能,都在用户档案中统一管理,则用户指向会员,查询用户时就能自动带出会员。当然,这样的设计会将用户指向会员的关系设计成聚合关系。

在一对一关系中,由于关系的双方都是通过主键来对应,因此在DSL中就不需要描述关联字段,只需要说明是一对一关系就行了。同时,如果是聚合关系,则在DSL中进行如下描述:

<join name="payment" joinType="oneToOne" isAggregation="true" class="com.edev.trade.order.entity.Payment"/>

接着,是多对一关系,它是领域建模中最常见的关系。如订单指向用户及用户地址、订单明细指向商品,都是多对一关系。在数据库设计时,通过一个外键就可以表示多对一关系。譬如,在以上案例中,在订单表中通过用户ID、地址ID,在订单明细表再通过商品ID,就能表示这种多对一关系。

在DSL中,多对一关系需要一个关联的字段。在订单对象中有一个用户ID,它就是用户对象的关联字段,在DSL中表示如下:

<join name="customer" joinKey="customerId" joinType="manyToOne" class="com.edev.trade.order.entity.Customer"/>

下一个关系是一对多关系,它实际上代表的是一种主子表的关系,如订单与订单明细、表单与表单明细、发票与发票明细。在这种关系中,订单只有一个,但它对应的订单明细却有多个。这样,在订单对象中的“订单明细”属性就不能是一个变量,而必须是一个集合变量,要么是Set,要么是List。这种关系如何映射成数据库设计呢?在数据库设计中没有一对多关系,然而将该关系倒过来,将订单明细指向订单,就变成了多对一关系。因此,在订单明细表中通过一个外键,就可以表示了。

这里就产生了一个问题了:在领域建模时,为什么不是订单明细指向订单呢?在这里实际上是一种聚合关系,订单是整体,订单明细是部分。如果设计成订单明细指向订单,那么这种聚合关系就消失了,我们必须得分别去管理订单和订单明细的增删改。在添加订单明细时,必须要检查它对应的订单是否存在;在删除订单时,也要检查它对应的订单明细是否已经被删除掉了,这样就会增大软件设计的复杂度。而将订单指向订单明细,则可以通过聚合关系将对订单明细的管理,封装在对订单的管理中。在增删改订单的同时,就在管理对订单明细的增删改,那么设计编码就得到了简化。代码简化了,日后的变更维护也就变得简单了。有了这样的设计,在编码的时候,首先将订单对象中增加一个订单明细的集合变量,然后在DSL中进行如下配置:

<join name="orderItems" joinKey="orderId" joinType="oneToMany" isAggregation="true" class="com.edev.emall.order.entity.OrderItem"/>

在这里,将该关系定义为了聚合关系。但毫无疑问,这种聚合关系的实现,需要底层“仓库”的支持。譬如,在更改订单时,我们如何知道客户是否对订单明细有增删改操作呢?这些问题我们在后面的文章中再与大家探讨。除此之外,以上案例的代码详见我的仓库:

Order.jave

order.xml

除了以上三个关系以外,还有“多对多”与继承关系。这两种关系在设计上都比较复杂,我将在下一期跟大家探讨。

相关的文章:

DDD你真的理解清楚了吗?怎么准确理解“值对象”

DDD你真的理解清楚了吗?充血模型 or 贫血模型

DDD你真的理解清楚了吗?非常抽象的聚合

(待续)

相关文章:

DDD该怎么去落地实现(1)关键是“关系”

DDD落地的关键是“关系” 这些年&#xff0c;我认为DDD走到了一个死胡同里了&#xff0c;因为落地实现过于困难。很多团队在经过一段时间的学习&#xff0c;清楚理解了DDD那些晦涩的概念&#xff0c;根据业务绘制出领域模型&#xff0c;这都不困难。但绘制领域模型不是我们最终…...

基于本地事务表+MQ实现分布式事务

基于本地事务表MQ实现分布式事务 引言1、原理2、本地消息表优缺点3、本地启动rocketmq4、代码实现及验证4.1、核心代码4.2、代码执行流程4.3、项目结构4.4、项目源码 引言 本地消息表的方案最初由ebay的工程师提出&#xff0c;核心思想是将分布式事务拆分成本地事务进行处理。…...

第17篇:python进阶:详解数据分析与处理

第17篇&#xff1a;数据分析与处理 内容简介 本篇文章将深入探讨数据分析与处理在Python中的应用。您将学习如何使用pandas库进行数据清洗与分析&#xff0c;掌握matplotlib和seaborn库进行数据可视化&#xff0c;以及处理大型数据集的技巧。通过丰富的代码示例和实战案例&am…...

S4 HANA Tax相关的定价过程

本文主要介绍在S4 HANA OP中Tax相关的定价过程相关设置。具体请参照如下内容&#xff1a; 目录 1. 定义定价过程(OBYZ) 2. 将定价过程分配给国家(OBBG)​编辑​编辑 3. 新增Transaction Key(OBCN) 1. 定义定价过程(OBYZ) 定价过程就是为了将“条件类型”和“事务”关联起来…...

Linux下php8安装phpredis扩展的方法

Linux下php8安装phpredis扩展的方法 下载redis扩展执行安装编辑php.ini文件重启php-fpmphpinfo 查看 下载redis扩展 前提是已经安装好redis服务了 php-redis下载地址 https://github.com/phpredis/phpredis 执行命令 git clone https://github.com/phpredis/phpredis.git执行…...

K8S 启动探测、就绪探测、存活探测

先来思考一个问题&#xff1a; 在 Deployment 执行滚动更新 web 应用的时候&#xff0c;总会出现一段时间&#xff0c;Pod 对外提供网络访问&#xff0c;但是页面访问却发生404&#xff0c;这个问题要如何解决呢&#xff1f;学完今天的内容&#xff0c;相信你会有自己的答案。 …...

rust学习-rust中的保留字

rust学习-rust中的保留字 已使用的保留字未来可能使用的保留字 保留字是语言中预定义的标识符&#xff0c;不能用作变量名、函数名或其他自定义标识符&#xff0c;Rust的保留字大致可以分为两类&#xff1a;已使用的保留字和未来可能使用的保留字 已使用的保留字 as&#xff1…...

-bash: ./uninstall.command: /bin/sh^M: 坏的解释器: 没有那个文件或目录

终端报错&#xff1a; -bash: ./uninstall.command: /bin/sh^M: 坏的解释器: 没有那个文件或目录原因&#xff1a;由于文件行尾符不匹配导致的。当脚本文件在Windows环境中创建或编辑后&#xff0c;行尾符为CRLF&#xff08;即回车和换行&#xff0c;\r\n&#xff09;&#xf…...

【C】memory 详解

<memory.h> 是一个 C 标准库头文件&#xff0c;提供了一组内存管理函数&#xff0c;用于分配、释放和操作动态内存。这些函数主要操作的是未初始化的内存块&#xff0c;是早期 C 编程中常用的内存操作工具。 尽管在现代 C 编程中更推荐使用<cstring>或<memory&…...

Android实训九 数据存储和访问

实训9 数据存储和访问 一、【实训目的】 1、 SharedPreferences存储数据; 2、 借助Java的I/O体系实现文件的存储&#xff0c; 3、使用Android内置的轻量级数据库SQLite存储数据; 二、【实训内容】 1、实现下图所示的界面&#xff0c;实现以下功能&#xff1a; 1&#xff…...

Redis vs. 其他数据库:深度解析,如何选择最适合的数据库?

一、如何为项目选择合适的数据库&#xff1f; 选择合适的数据库是一个复杂的过程&#xff0c;需要综合考虑多个因素。下面几个维度来详细阐述&#xff1a; 1.数据模型 关系型数据库&#xff08;RDBMS&#xff09;&#xff1a;适用于高度结构化、关联性强的数据&#xff0c;如电…...

docker 安装 mysql 详解

在平常的开发工作中&#xff0c;我们经常需要用到 mysql 数据库。那么在docker容器中&#xff0c;应该怎么安装mysql数据库呢。简单来说&#xff0c;第一步&#xff1a;拉取镜像&#xff1b;第二步&#xff1a;创建挂载目录并设置 my.conf&#xff1b;第三步&#xff1a;启动容…...

C++实现设计模式---桥接模式 (Bridge)

桥接模式 (Bridge) 桥接模式 是一种结构型设计模式&#xff0c;它通过将抽象部分与实现部分分离&#xff0c;使它们可以独立变化。桥接模式的核心思想是使用组合&#xff08;而非继承&#xff09;来扩展功能。 意图 将抽象部分与实现部分分离&#xff0c;使它们都可以独立地变…...

LangChain + llamaFactory + Qwen2-7b-VL 构建本地RAG问答系统

单纯仅靠LLM会产生误导性的 “幻觉”&#xff0c;训练数据会过时&#xff0c;处理特定知识时效率不高&#xff0c;缺乏专业领域的深度洞察&#xff0c;同时在推理能力上也有所欠缺。 正是在这样的背景下&#xff0c;检索增强生成技术&#xff08;Retrieval-Augmented Generati…...

pycharm 运行远程环境问题 Error:Failed to prepare environment.

问题排查 拿到更详细的报错信息&#xff1a; Help > Diagnostic Tools > Debug Log Settings section: 添加下面的配置 com.intellij.execution.configurations.GeneralCommandLine 重显报错&#xff0c;我这里是再次运行代码打开 Help | Collect Logs and Diagnosti…...

Level2逐笔成交逐笔委托毫秒记录:今日分享优质股票数据20250124

逐笔成交逐笔委托下载 链接: https://pan.baidu.com/s/1UWVY11Q1IOfME9itDN5aZA?pwdhgeg 提取码: hgeg Level2逐笔成交逐笔委托数据分享下载 通过Level2逐笔成交与逐笔委托的详细数据&#xff0c;这种以毫秒为单位的信息能揭示许多关键点&#xff0c;如庄家意图、误导性行为…...

最新最详细的配置Node.js环境教程

配置Node.js环境 一、前言 &#xff08;一&#xff09;为什么要配置Node.js&#xff1f;&#xff08;二&#xff09;NPM生态是什么&#xff08;三&#xff09;Node和NPM的区别 二、如何配置Node.js环境 第一步、安装环境第二步、安装步骤第三步、验证安装第四步、修改全局模块…...

【Address Overfitting】解决过拟合的三种方法

目录 1. 收集更多数据实践方法&#xff1a;适用场景&#xff1a;优缺点&#xff1a; 2. 特征选择方法介绍&#xff1a;实践示例&#xff1a;适用场景&#xff1a;优缺点&#xff1a; 3. 正则化&#xff08;Regularization&#xff09;正则化类型&#xff1a;实践示例&#xff1…...

【缘于J2ME】

我与 J2ME 的不解之缘 那年我 25 岁&#xff0c;如今已即将退休。 在那个娱乐生活并不丰富的年代&#xff0c;每每响起「小霸王其乐无穷啊」&#xff0c;小伙伴们就会摩拳擦掌、轮番上阵&#xff0c;而我却痴迷于 G-BASIC 编程。 最大的乐趣就是对着仅有的两页说明&#xff0c…...

c#使用log4Net配置日志文件

1.# 写一个通用类 LogHelper using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using log4net;namespace WindowsFormsApplication22 {public class LogHelper{static ILog mylog LogManager.GetLogge…...

[ACTF2020 新生赛]Include1

题目 点击tips后&#xff1a; 使用PHP伪协议直接读取flag /?filephp://filter/readconvert.base64-encode/resourceflag.php base64解码 拿下flag flag{6cce5a3d-997a-4c8a-ba07-f6652ee462a9}...

【数据结构】树的基本:结点、度、高度与计算

树是数据结构中一种重要的非线性结构&#xff0c;广泛应用于计算机科学的各个领域&#xff0c;例如文件系统、数据库索引、编译器等。理解树的各种性质&#xff0c;如结点数、度、高度等&#xff0c;对于解决实际问题至关重要。 本文将会探讨树的基本概念&#xff0c;以及给出几…...

1.24 共享内存和信号灯集

使用共享内存信号灯集实现两个进程之间相互对话。 程序代码&#xff1a; #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stst.h> #include <fcntl.h> #…...

正则表达式以及Qt中的使用

目录 一、正则表达式 1、基本匹配&#xff1a; 2、元字符&#xff1a; 2.1 .运算符&#xff1a; 2.2 字符集&#xff1a; 2.3 重复次数&#xff1a; 2.4 量词{} 2.5 特征标群() 2.6 或运算符 2.7 \反斜线转码特殊字符 2.8 锚点 3、简写字符 4、零宽度断言 4.1 正…...

STM32简介

STM32简介 STM32是ST公司基于ARMCortex-M内核开发的32位微控制器 &#xff08;Microcontroller&#xff09; MCU微控制器、MPU微处理器、CPU中央处理器 1.应用领域 STM32常应用于嵌入式领域。 如智能车&#xff1a;循迹小车 读取光电传感器或者摄像头的数据&#xff0c;…...

【设计模式-行为型】访问者模式

一、什么是访问者模式 说起来访问者模式&#xff0c;其实很少用。我一直在思考该用什么样的例子把这个设计模式表述清晰&#xff0c;最近突然想到一个例子也许他就是访问者。港片有过很辉煌的年代&#xff0c;小的时候一直在看港片觉得拍的非常好&#xff0c;而且演员的演技也在…...

上海亚商投顾:沪指冲高回落 大金融板块全天强势 上海亚商投

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一&#xff0e;市场情绪 市场全天冲高回落&#xff0c;深成指、创业板指午后翻绿。大金融板块全天强势&#xff0c;天茂集团…...

docker部署jenkins

环境&#xff1a; centos7.9 jenkins/jenkins:lts-jdk11 1、拉去jenkins镜像&#xff0c;请指明版本号 [rootlocalhost ~]# docker pull jenkins/jenkins:lts 开始拉取 拉取完成 [rootlocalhost ~]# docker pull jenkins/jenkins:lts lts: Pulling from jenkins/jenkins 0a9…...

初阶数据结构:链表(二)

目录 一、前言 二、带头双向循环链表 1.带头双向循环链表的结构 &#xff08;1)什么是带头&#xff1f; (2)什么是双向呢&#xff1f; &#xff08;3&#xff09;那什么是循环呢&#xff1f; 2.带头双向循环链表的实现 &#xff08;1&#xff09;节点结构 &#xff08;2…...

Django实现数据库的表间三种关系

Django实现数据库的表间三种关系 1. 一对多&#xff08;One-to-Many&#xff09;关系示例&#xff1a;关系说明&#xff1a;查询示例&#xff1a; 2. 一对一&#xff08;One-to-One&#xff09;关系示例&#xff1a;关系说明&#xff1a;查询示例&#xff1a; 3. 多对多&#x…...

AI导航工具我开源了利用node爬取了几百条数据

序言 别因今天的懒惰&#xff0c;让明天的您后悔。输出文章的本意并不是为了得到赞美&#xff0c;而是为了让自己能够学会总结思考&#xff1b;当然&#xff0c;如果有幸能够给到你一点点灵感或者思考&#xff0c;那么我这篇文章的意义将无限放大。 背景 随着AI的发展市面上…...

概率密度函数(PDF)分布函数(CDF)——直方图累积直方图——直方图规定化的数学基础

对于连续型随机变量&#xff0c;分布函数&#xff08;Cumulative Distribution Function, CDF&#xff09;是概率密度函数&#xff08;Probability Density Function, PDF&#xff09;的变上限积分&#xff0c;概率密度函数是分布函数的导函数。 如果我们有一个连续型随机变量…...

OpenHarmony OTA升级参考资料记录

OpenHarmony 作为一个开源分布式操作系统,通过其强大的 OTA(Over-The-Air)升级能力,为开发者和厂商提供了一套灵活而安全的系统升级方案。 OTA升级方式 根据升级包的应用方式,OpenHarmony 的 OTA 升级可以分为两种:本地升级和网络OTA升级。 本地升级 本地升级是将已制作…...

从 Spark 到 StarRocks:实现58同城湖仓一体架构的高效转型

作者&#xff1a;王世发&#xff0c;吴艳兴等&#xff0c;58同城数据架构部 导读&#xff1a; 本文介绍了58同城在其数据探查平台中引入StarRocks的实践&#xff0c;旨在提升实时查询性能。在面对传统Spark和Hive架构的性能瓶颈时&#xff0c;58同城选择StarRocks作为加速引擎&…...

网络知识小科普--5

81、什么是组播路由? 组播路由是一种有针对性的广播形式&#xff0c;将消息发送到所选择的用户组&#xff0c;而不是将其发送到子网上的所有用户。 82、加密在网络上的重要性是什么? 加密是将信息转换成用户不可读的代码的过程。然后使用秘密密钥或密码将其翻译或解密回其…...

【JWT】jwt实现HS、RS、ES、ED签名与验签

JWT 实现 HS、RS、ES 和 ED 签名与验签 签名方式算法密钥类型签名要点验签要点HSHMAC-SHA256对称密钥- 使用 crypto/hmac 和对称密钥生成 HMAC 签名- 将 header.payload 作为数据输入- 使用同一密钥重新计算 HMAC 签名- 比较计算结果与接收到的签名是否一致RSRSA-SHA256公钥 …...

cherry USB 键盘分析

文章目录 cherry USB 键盘分析描述符结构设备描述符配置描述符集合配置描述符接口 1 描述符HID 描述符端点 IN 描述符接口 2 描述符HID 描述符端点 IN 描述符端点 OUT 描述符字符串描述符语言 ID (字符串索引为 0)厂商字符串(字符串索引为 1)产品字符串(字符串索引为 2)HID 报告…...

R语言学习笔记之高效数据操作

一、概要 数据操作是R语言的一大优势&#xff0c;用户可以利用基本包或者拓展包在R语言中进行复杂的数据操作&#xff0c;包括排序、更新、分组汇总等。R数据操作包&#xff1a;data.table和tidyfst两个扩展包。 data.table是当前R中处理数据最快的工具&#xff0c;可以实现快…...

高阶C语言|数组名的深度解析(数组名结合sizeof与strlen的详解)

&#x1f4ac; 欢迎讨论&#xff1a;在阅读过程中有任何疑问&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;如果你觉得这篇文章对你有帮助&#xff0c;记得点赞、收藏&#xff0c;并分享给更多对C语言感兴…...

Vue3 v-bind 和 v-model 对比

1. 基本概念 1.1 v-bind 单向数据绑定从父组件向子组件传递数据简写形式为 : 1.2 v-model 双向数据绑定父子组件数据同步本质是 v-bind 和 v-on 的语法糖 2. 基础用法对比 2.1 表单元素绑定 <!-- v-bind 示例 --> <template><input :value"text&quo…...

科家多功能美发梳:科技赋能,重塑秀发新生

在繁忙的都市生活中,头皮健康与秀发养护成为了现代人不可忽视的日常课题。近日,科家电动按摩梳以其卓越的性能和创新设计,赢得了广大消费者的青睐。这款集科技与美学于一身的美发梳,不仅搭载了2亿负离子、6000次/分钟的声波振动等前沿技术,更融入了650nm聚能环红光与415nm强劲蓝…...

systemverilog中的force,release和assign

1 assign assign 语句用于为 wire 类型的信号提供连续赋值。它建立了一个驱动源&#xff0c;根据右侧表达式的值持续驱动 wire 信号。 module Example;wire a, b, c;assign c a & b; endmodule 2 force force 用于强制将一个信号的值设定为某个特定值&#xff0c;会覆盖…...

9【如何面对他人学习和生活中的刁难】

我们在学习的过程中&#xff0c;会遇到很多来自于他人的刁难与嘲讽&#xff0c;如果处理不好&#xff0c;这会大大影响我们的心情&#xff0c;从而影响学习的效率 我建议&#xff0c;如果你学习或生活中也遇到了类似的问题&#xff0c;不要去生气&#xff0c;更不要发生冲突&a…...

新项目传到git步骤

1.首先创建远程仓库,创建一个空白项目,即可生成一个克隆URL,可以是http也可以是SSH,copy下这个地址 2.找到项目的本机目录,进入根目录,打开git bash here命令行 3.初始化: git init 4.关联远程地址: git remote add origin "远程仓库的URL" 5.查看关联 git re…...

docker搭建redis集群(三主三从)

本篇文章不包含理论解释&#xff0c;直接开始集群&#xff08;三主三从&#xff09;搭建 环境 centos7 docker 26.1.4 redis latest &#xff08;7.4.2&#xff09; 服务器搭建以及环境配置 请查看本系列前几篇博客 默认已搭建好三个虚拟机并安装配置好docker 相关博客&#xf…...

DDD架构实战第七讲总结:分层模型和代码组织

云架构师系列课程之DDD架构实战第七讲总结:分层模型和代码组织 一、引言 在前几讲中,我们介绍了领域驱动设计(DDD)的基本构造块和生命周期模型中的聚合。本讲将重点讨论如何将这些构造块和代码组织起来,探讨分层架构和六边形模型,以及如何组织代码结构。 二、工厂和资…...

LabVIEW太阳能照明监控系统

在公共照明领域&#xff0c;传统的电力照明系统存在高能耗和维护不便等问题。利用LabVIEW开发太阳能照明监控系统&#xff0c;通过智能控制和实时监测&#xff0c;提高能源利用效率&#xff0c;降低维护成本&#xff0c;实现照明系统的可持续发展。 ​ 项目背景 随着能源危机…...

C# 结构体

总目录 前言 在 C# 编程中&#xff0c;结构体&#xff08;struct&#xff09;是一种非常重要的数据结构&#xff0c;它为我们提供了一种轻量级的存储和操作数据的方式。本教程将带你深入了解结构体的概念、特点、使用方法&#xff0c;以及一些使用结构体的最佳实践。 一、什么…...

C++小病毒-1.0勒索(更新次数:1)

内容供学习使用,不得转卖,代码复制后请1小时内删除,此代码会危害计算机安全,谨慎操作 在C20环境下,并在虚拟机里运行此代码!&#xff0c;病毒带来后果自负! 使用时请删除在main()里的注释,并修改位置至C:\\(看我代码注释)//可以改成WIN Main() #include <iostream> #i…...

RabbitMQ---面试题

常见面试题 1.MQ的作用及应用场景 类似问题&#xff1a;项目什么情况下用到了MQ&#xff0c;为什么要用MQ MQ的主要应用场景&#xff0c;消息队列的应用场景&#xff0c;为什么说消息队列可以削峰 首先MQ是一种用来接收和转发消息的队列&#xff0c;常见的应用常见如下&…...