DDD-战略设计 vs 战术设计

在领域驱动设计(DDD)中,战略设计战术设计是两个不同的层次,分别解决不同粒度的问题。

1. 战略设计(Strategic Design)

定义:
战略设计关注高层次的架构和业务边界,定义系统的整体结构,确保各个领域和团队的协调工作。其核心是划分限界上下文(Bounded Context),并识别核心领域,从而为业务建模提供清晰的边界和指导。

核心概念:

  • 限界上下文(Bounded Context): 定义不同业务子领域的边界,确保模型在该边界内的一致性。
  • 领域(Domain): 业务的整体范畴,例如电商、物流、支付等。
  • 子领域(Subdomain): 具体的业务部分,例如电商中的“订单管理”、“库存管理”。
  • 上下文映射(Context Mapping): 描述限界上下文之间的关系(合作、依赖、反腐等模式)。
  • 核心域、支撑域、通用域的划分: 确定哪些部分是企业的核心竞争力,哪些是通用或辅助功能。

举例:
假设你正在设计一个在线购物平台,可以将其分为多个限界上下文

  1. 订单管理上下文: 处理订单的创建、支付和发货。
  2. 用户管理上下文: 处理用户注册、登录和账户管理。
  3. 库存管理上下文: 负责库存的增加、减少以及供应链管理。
  4. 支付上下文: 处理支付网关对接、账单管理等。

在战略设计阶段,你需要明确:

  • 这些上下文之间的边界,避免相互干扰。
  • 如何沟通,例如订单系统和库存系统通过API交互。
  • 识别核心域(订单),支撑域(用户管理),以及通用域(支付)。

2. 战术设计(Tactical Design)

定义:
战术设计关注具体领域模型的实现,即如何在每个限界上下文内部设计领域对象,保证业务逻辑的合理性和一致性。其核心在于用面向对象的方式来设计领域模型。

核心概念:

  • 实体(Entity): 有唯一标识的业务对象,例如“订单编号”。
  • 值对象(Value Object): 无唯一标识,通常不可变,例如“地址”。
  • 聚合(Aggregate): 一组具有业务完整性的对象集合,例如“订单”聚合包含订单明细、收件人信息。
  • 聚合根(Aggregate Root): 负责管理聚合内的所有对象,保证一致性。
  • 领域服务(Domain Service): 处理跨多个实体的复杂业务逻辑。
  • 仓储(Repository): 负责持久化聚合对象。

举例:
在“订单管理上下文”中,战术设计的实现可能包含:

class Order {
    private $orderId;
    private $items = [];
    private $status;

    public function __construct($orderId) {
        $this->orderId = $orderId;
        $this->status = "pending";
    }

    public function addItem(Product $product, $quantity) {
        $this->items[] = new OrderItem($product, $quantity);
    }

    public function confirmOrder() {
        if (empty($this->items)) {
            throw new Exception("Order must have at least one item.");
        }
        $this->status = "confirmed";
    }

    public function getStatus() {
        return $this->status;
    }
}

class OrderItem {
    private $product;
    private $quantity;

    public function __construct(Product $product, $quantity) {
        $this->product = $product;
        $this->quantity = $quantity;
    }
}
  • Order 是一个实体,具有唯一的orderId
  • OrderItem 是值对象,表示订单中的具体商品项。
  • 订单管理逻辑封装在 confirmOrder() 方法中,确保订单完整性。

3. 战略设计 vs. 战术设计的区别

对比维度战略设计(Strategic Design)战术设计(Tactical Design)
关注点业务边界、上下文划分、架构层次领域模型、对象设计、业务逻辑
主要目标划分清晰的上下文,减少依赖设计良好的领域模型以执行业务逻辑
设计内容限界上下文、上下文映射、领域划分实体、值对象、聚合、服务、仓储等
粒度高层次(整个系统级)低层次(某个上下文内部)
结果系统架构、服务划分具体代码实现

4. 总结

  • 战略设计:站在业务全局角度,划分系统的各个上下文和边界,明确它们如何协作。例如,将“订单管理”与“库存管理”区分开来。
  • 战术设计:深入到具体实现层面,设计领域对象及其交互方式。例如,定义订单如何管理商品项、如何更改状态。

简单类比:

  • 战略设计 = 规划城市布局,决定住宅区、商业区、工业区。
  • 战术设计 = 具体在住宅区中,设计楼房的结构、房间布局等。

是的,战略设计战术设计是**领域驱动设计(DDD)**中不可缺少的两个关键部分。它们共同作用,确保在复杂业务领域中,系统既具备高层次的架构规划,又能落实到细节的领域模型实现。两者相辅相成,缺一不可。

为什么战略设计不可缺少?

1. 确保业务与技术对齐

  • 战略设计帮助团队从业务角度划分系统,定义限界上下文(Bounded Context),确保每个部分都有清晰的业务职责,避免“一个模型打天下”的混乱局面。
  • 如果缺少战略设计,系统很可能变得耦合混乱,导致业务逻辑交错难以维护。

2. 解决复杂业务的划分问题

  • 在复杂业务场景中,如电商、金融等,往往有多个子系统,例如“订单管理”“库存管理”“支付处理”等。战略设计可以有效划分边界,减少模块之间的依赖,实现团队协作的独立性
  • 如果没有战略设计,可能会导致职责不清、业务逻辑相互干扰,维护困难

3. 支持团队协作

  • 大型企业通常由不同团队负责不同的业务子领域。战略设计确保各团队在清晰边界下开发,降低沟通成本,提升开发效率。
  • 没有战略设计,不同团队可能会在同一领域重复建模,造成数据不一致和开发浪费。

4. 促进技术架构的演进

  • 战略设计能够确保系统在扩展性和可维护性上的合理规划,比如微服务架构的拆分,或系统的模块化演进。
  • 如果没有战略设计,系统可能会在后期由于不合理的架构决策而面临高昂的改造成本。

总结:
战略设计不可缺少,因为它从宏观层面帮助团队建立合理的架构边界,确保业务逻辑的清晰性、团队协作的顺畅性,以及系统的长期可扩展性。

为什么战术设计不可缺少?

1. 确保领域逻辑的正确性

  • 战术设计关注具体的领域模型,比如如何设计实体(Entity)、值对象(Value Object)、聚合(Aggregate)等,以保证业务逻辑的一致性和完整性
  • 如果缺少战术设计,领域逻辑可能会散落在代码的各个角落,导致难以维护和扩展。

2. 避免贫血模型,聚合业务逻辑

  • 通过战术设计,业务逻辑被放入领域对象中,而不是仅仅依赖于服务或数据库。这样可以减少**“贫血模型”**(只存储数据,不包含行为)的情况,使模型更贴近业务。
  • 没有战术设计,系统容易演变成一个CRUD式架构,业务规则分散在控制器、服务层,导致高耦合、低内聚。

3. 提供灵活的业务扩展能力

  • 通过战术设计,利用**聚合根(Aggregate Root)领域服务(Domain Service)**来封装复杂的业务逻辑,确保系统能随业务需求的变化进行调整。
  • 缺少战术设计,扩展业务时往往会修改多个模块,增加开发和维护成本。

4. 确保一致性和事务控制

  • 战术设计通过聚合的概念,控制数据的一致性,确保对聚合的操作在事务边界内完成,避免数据不一致问题。
  • 如果没有战术设计,事务逻辑可能会在多个组件之间分散,导致数据处理混乱。

总结:
战术设计不可缺少,因为它从微观层面确保系统的业务逻辑实现合理、可维护,避免贫血模型,提高系统的可扩展性。

两者如何相辅相成?

如果只做战略设计,而不做战术设计:

  • 可能会有清晰的架构规划,但在实现细节上缺乏合理的业务建模,导致代码实现复杂、难以维护。

如果只做战术设计,而不做战略设计:

  • 可能会有合理的领域建模,但在整体架构上缺乏边界划分,导致不同模块之间相互耦合,难以扩展。

一个完整的DDD实施流程应该是这样的:

  1. 先做战略设计,确定各业务上下文的边界、团队分工。
  2. 然后做战术设计,在每个上下文内部实现高质量的领域模型。

举例:电商系统

层次战略设计战术设计
定义识别业务边界,划分上下文设计领域对象,确保业务逻辑一致性
示例划分“订单管理”“库存管理”上下文定义“订单”实体、聚合、服务
结果清晰的架构边界,避免模块耦合代码层面业务逻辑清晰可维护

结论

战略设计和战术设计都是DDD不可或缺的组成部分。

  • 战略设计决定系统的边界和结构,帮助管理复杂性;
  • 战术设计确保业务逻辑的实现,保证代码的高质量。

DDD成功实施的关键在于:
"战略设计决定大的方向,战术设计决定落地效果,二者缺一不可。"

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python中采用.add_subplot绘制子图的方法简要举例介绍

Python中采用.add_subplot绘制子图的方法简要举例介绍 目录 Python中采用.add_subplot绘制子图的方法简要举例介绍一、Python中绘制子图的方法1.1 add_subplot函数1.2 基本语法(1)add_subplot的核心语法(2)add_subplot在中编程中的…

考研408笔记之数据结构(五)——图

数据结构(五)——图 1. 图的基本概念 1.1 图的定义 1.2 有向图和无向图 在有向图中,使用圆括号表示一条边,圆括号里元素位置互换没有影响。 在无向图中,使用尖括号表示一条边,尖括号里元素位置互换则表示…

研究生阶段 |《最优化方法》

文章目录 一、前言二、章节2.1 绪论2.1.1 最优化数学模型什么是最优化问题?最优化问题的数学模型最优解的一般概念最优化理论和方法?理论和方法有什么区别?最优化问题的分类具体的学习内容 2.1.2 用到的基本数学知识范数与内积方向导数、梯度、子梯度、Hesse矩阵以及Jacobi矩…

【软件测试项目实战 】淘宝网:商品购买功能测试

一、用例设计方法分析 在对淘宝网商品下单功能进行测试时,不同的测试角度和场景适合运用不同的用例设计方法,以下是针对该功能各方面测试所适用方法及其原因的分析: 商品数量相关测试:对于商品数量的测试,主要采用等…

全球化趋势与中资企业出海背景

1. 全球化趋势与中资企业出海背景 1.1 全球经济格局变化 全球经济格局正经历深刻变革,新兴经济体崛起,全球产业链重塑,中资企业出海面临新机遇与挑战。据世界银行数据,新兴市场和发展中经济体在全球 GDP 中占比已超 40%&#xff…

微信小程序web-view打开网页与网页H5跳转微信小程序

1、微信小程序web-view打开网页 目前从小程序进入网页的方法使用web-view 1.1、小程序官网需要配置业务域名 打开官网,选择左侧开发管理,选择开发设置,往下找到业务域名,添加域名。设置时需要下载校验文件,并将文件…

登录认证(4):令牌技术:JWT令牌

如上文所说(登录认证(1):登录的基本逻辑及实现思路登录),因为 HTTP协议是无状态的协议,我们需要使用会话跟踪技术实现同一会话中不同请求之间的数据共享,但Cookie技术和Session技术都…

Powershell-2

声明:学习视频来自b站up主 泷羽sec,如涉及侵权马上删除文章 感谢泷羽sec 团队的教学 视频地址:powershell(2)_哔哩哔哩_bilibili 一 、Powershell使用外部命令 在 Powershell 中,可以执行一些外部命令&…

Flowable 管理各业务流程:流程设计器 (获取流程模型 XML)、流程部署、启动流程、流程审批、流程挂起和激活、任务分配

文章目录 引言I 表结构主要表前缀及其用途核心表II 流程设计器(Flowable BPMN模型编辑器插件)Flowable-UIvue插件III 流程部署部署步骤例子:根据流程模型ID部署IV 启动流程启动步骤ACT_RE_PROCDEF:流程定义相关信息例子:根据流程 ID 启动流程V 流程审批审批步骤Flowable 审…

快速入门Flink

Flink是新一代实时计算平台,采用原生的流处理系统,保证了低延迟性,在API和容错上也是做的相当完善,本文将从架构、组件栈、安装、入门程序等进行基础知识的分析,帮助大家快速对Flink有一个了解。 一.简介 1.是什么 Ap…

VOSK实现【离线中文语音】识别

Vosk是一款开源的离线语音识别工具包,具有以下功能: 多语言支持:能够对20多种语言和方言进行语音识别,如中文、英语、德语、法语、西班牙语等,可满足不同用户的语言需求。 模型轻量化:每种语言的模型大小仅…

最新版pycharm如何配置conda环境

首先在conda prompt里创建虚拟环境,比如 conda create --prefix E:/projects/myenv python3.8然后激活 conda activate E:/projects/myenv往里面安装点自己的包,比如 conda install pytorch1.7.1 torchvision0.8.2 -c pytorch打开pycharm 注意&#x…

MySQL用户授权、收回权限与查看权限

【图书推荐】《MySQL 9从入门到性能优化(视频教学版)》-CSDN博客 《MySQL 9从入门到性能优化(视频教学版)(数据库技术丛书)》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) MySQL9数据库技术_夏天又到了…

【vitpress】静态网站添加访问量统计

这里要是用的插件是不蒜子。 1.安装插件 npm i busuanzi.pure.js2.添加VisitorPanel.vue文件 在.vitepress/theme/components文件添加VisitorPanel.vue文件&#xff0c;内容如下&#xff1a; <!-- .vitepress/theme/components/VisitorPanel.vue --> <template>…

Data Filtering Network 论文阅读和理解

目录 一、TL&#xff1b;DR 二、Introduction 2.1 apple的结论 2.2 业界做法&#xff1a; 2.3 我们的做法&#xff08;Apple&#xff09; 2.4 如何获取好的DFN 三、未完待续&#xff08;这周出去购物了&#xff0c;下周继续补充&#xff09; 一、TL&#xff1b;DR 核心…

MATLAB绘图时线段颜色、数据点形状与颜色等设置,介绍

MATLAB在绘图时&#xff0c;设置线段颜色和数据点的形状与颜色是提高图形可读性与美观性的重要手段。本文将详细介绍如何在 MATLAB 中设置这些属性。 文章目录 线段颜色设置单字母颜色表示法RGB 值表示法 数据点的形状与颜色设置设置数据点颜色和形状示例代码 运行结果小结 线段…

部署 Harbor 私有云仓库

参考链接&#xff1a;https://docs.tianshu.org.cn/docs/setup/deploy-harbor-cloud-warehouse 使用

150 Linux 网络编程6 ,从socket 到 epoll整理。listen函数参数再研究

一 . 只能被一个client 链接 socket例子 此例子用于socket 例子&#xff0c; 该例子只能用于一个客户端连接server。 不能用于多个client 连接 server socket_server_support_one_clientconnect.c /* 此例子用于socket 例子&#xff0c; 该例子只能用于一个客户端连接server。…

Java基础 (一)

基础概念及运算符、判断、循环 基础概念 关键字 数据类型 分为两种 基本数据类型 标识符 运算符 运算符 算术运算符 隐式转换 小 ------>>> 大 强制转换 字符串 拼接符号 字符 运算 自增自减运算符 ii赋值运算符 赋值运算符 包括 强制转换 关系运算符 逻辑运算符 …

项目集成RabbitMQ

文章目录 1.common-rabbitmq-starter1.创建common-rabbitmq-starter2.pom.xml3.自动配置1.RabbitMQAutoConfiguration.java2.spring.factories 2.测试使用1.创建common-rabbitmq-starter-demo2.目录结构3.pom.xml4.application.yml5.TestConfig.java 配置交换机和队列6.TestCon…