news 2026/7/10 2:54:15

【业务与技术架构】从胖 Service 到清晰架构:用 DDD 看业务,用 COLA 放代码

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【业务与技术架构】从胖 Service 到清晰架构:用 DDD 看业务,用 COLA 放代码

文章目录

    • 一、从 ChatBI 大泥球看 DDD 与 COLA 的分工
    • 二、DDD 与 COLA 的关系:业务治理地图与代码货架
    • 三、ChatBI 案例:从胖 Service 到 DDD + COLA
    • 四、回到架构思维:控制变化,而不是堆架构
    • 结语

ChatBI 系统一开始通常很简单:用户输入一个问题,系统把问题交给大模型,生成 SQL,查询数据库,再把结果返回给用户。

这个流程看起来像一条直线,所以很多项目最初会把它写在一个ChatServiceImpl里。

后来需求越来越多:要识别指标口径,要做权限校验,要选择数据集,要改写用户问题,要生成 SQL,要校验 SQL,要查数仓,要解释图表,要记录会话,还要做安全审计。

于是一个 ChatBI 服务很快变成这样:

接收用户问题 识别意图 选择数据集 解析指标口径 拼 Prompt 调用大模型 生成 SQL 校验 SQL 检查权限 执行查询 生成图表 组织自然语言回答 记录会话 埋点审计

代码还能跑,但系统已经开始变重。问题不只是方法太长,而是几类完全不同的复杂度被塞到一起了。

ChatBI 的复杂度至少有四类:

入口复杂度:Web、API、消息、插件入口 流程复杂度:一次问答要经过多个步骤 业务复杂度:指标、口径、权限、数据集、问答语义 技术复杂度:LLM、向量库、数仓、缓存、审计、消息

如果这些都挤在一个ChatServiceImpl里,任何变化都会牵动它:模型换了要改,指标口径变了要改,权限规则变了要改,SQL 引擎换了也要改。

这就是架构开始失控的地方。

DDD 和 COLA 的价值,要从这里理解:

DDD 解决:ChatBI 的业务概念和规则怎么建模。 COLA 解决:这些模型、流程和技术实现应该放在哪里。

先看清业务,再安放代码。

一、从 ChatBI 大泥球看 DDD 与 COLA 的分工

ChatBI 最容易写成一个“智能问答大方法”。

比如:

public ChatAnswerDTO ask(ChatRequest request) { User user = userService.getUser(request.getUserId()); DatasetDTO dataset = datasetService.matchDataset(request.getQuestion()); if (!permissionService.canAccess(user, dataset)) { throw new BizException("无数据集权限"); } MetricDTO metric = metricService.resolveMetric(request.getQuestion(), dataset); String prompt = promptBuilder.build(request.getQuestion(), dataset, metric); String sql = llmClient.generateSql(prompt); sqlValidator.validate(sql); List<Map<String, Object>> rows = warehouseClient.query(sql); ChartDTO chart = chartService.buildChart(request.getQuestion(), rows); String summary = llmClient.summarize(request.getQuestion(), rows); chatRecordMapper.insert(request, sql, rows, summary); auditService.record(user, dataset, sql); return new ChatAnswerDTO(summary, chart); }

这段代码表面上是在回答一个问题,实际上混了很多职责:

用户入口处理 问答流程编排 指标和口径识别 数据集权限判断 Prompt 构造 LLM 调用 SQL 校验 数仓查询 图表生成 会话记录 审计记录

真正的问题不是“代码长”,而是这些职责的变化来源不同。

权限规则变化,不应该影响 LLM 调用代码。
指标口径变化,不应该影响 Controller。
模型供应商变化,不应该影响 ChatBI 的领域规则。
数仓查询方式变化,不应该影响问答语义建模。

DDD 首先帮我们看清:这里哪些是 ChatBI 的业务概念。

在 ChatBI 里,真正重要的业务概念可能不是RequestResponseMapper,而是:

Question:用户问题 Conversation:会话 Dataset:数据集 Metric:指标 Dimension:维度 SemanticModel:语义模型 QueryIntent:查询意图 SqlDraft:待校验 SQL Answer:回答 DataPermission:数据权限

这些概念不是为了“显得领域化”,而是因为业务人员、数据产品、数据开发都会围绕它们沟通。

DDD 要问的是:

用户问题如何被理解? 指标口径由谁决定? 数据集选择规则是什么? 权限检查基于用户、数据集,还是字段级权限? SQL 生成前后分别要满足什么规则? 回答结果是否属于一次会话的一部分?

这些问题的目标,是把 ChatBI 的核心业务规则从技术流程里分离出来。

COLA 接着处理代码安放问题。

它把代码按职责放到不同层:

Adapter:接收外部请求 App:编排一次 ChatBI 问答用例 Domain:表达 ChatBI 的核心业务概念和规则 Infrastructure:适配 LLM、数仓、向量库、权限系统、审计系统 Client:定义对外命令、查询、DTO

所以二者分工很清楚:

DDD 帮你识别 ChatBI 的业务模型。 COLA 帮你把入口、流程、规则、技术实现分开放。

二、DDD 与 COLA 的关系:业务治理地图与代码货架

DDD 和 COLA 都会提到domain,但它们不是一回事。

DDD 是业务建模方法。它关心的是 ChatBI 世界里到底有哪些稳定概念,以及规则属于谁

比如:

什么是指标? 什么是维度? 什么是语义模型? 什么叫用户有权限问这个问题? 什么叫 SQL 安全? 什么叫一个回答可信?

COLA 是应用架构。它关心的是这些概念和规则写出来后,应该放在哪一层

adapter 放 HTTP、RPC、消息入口 app 放 AskQuestionAppService 这类用例编排 domain 放 Question、Metric、Dataset、SemanticModel 等领域对象 infrastructure 放 LLM、数仓、向量库、审计、外部权限系统适配 client 放 AskQuestionCmd、ChatAnswerDTO 等契约

所以,DDD 不等于 COLA。

你可以用 DDD 建模 ChatBI,但不用 COLA。
你也可以套了 COLA 目录,但 ChatBI 逻辑仍然贫血。

二者更准确的关系是:

DDD 是业务地图,COLA 是代码货架。

业务地图回答:

ChatBI 里有哪些关键业务概念? 一次问答的规则属于谁? 哪些概念属于语义层,哪些属于查询执行层? 权限、指标、SQL 安全的边界在哪里?

代码货架回答:

入口放哪里? 用例编排放哪里? 业务规则放哪里? LLM 和数仓调用放哪里? 对外 DTO 放哪里?

比如 DDD 识别出这些领域概念:

Question QueryIntent SemanticModel Metric Dataset DataPermission SqlDraft Answer

COLA 可以这样承载:

domain/chat/Question.java domain/chat/Conversation.java domain/semantic/SemanticModel.java domain/semantic/Metric.java domain/dataset/Dataset.java domain/security/DataPermission.java domain/query/SqlDraft.java domain/answer/Answer.java

一次问答用例放在:

app/AskQuestionAppService.java

外部入口放在:

adapter/web/ChatController.java

技术实现放在:

infrastructure/llm/LlmGatewayImpl.java infrastructure/warehouse/WarehouseGatewayImpl.java infrastructure/vector/VectorSearchGatewayImpl.java infrastructure/audit/ChatAuditGatewayImpl.java

如果只是把ChatServiceImpl挪到domain/chat/ChatService,但里面仍然直接调 LLM、拼 Prompt、查数仓、写审计,那不是架构升级,只是换目录。

判断 COLA 有没有真正发挥作用,看三个问题:

ChatBI 的业务规则是不是进入了 Domain? LLM、数仓、向量库是不是隔离在 Infrastructure? App 层是不是只编排流程,而不是吞掉所有逻辑?

把 DDD 和 COLA 合起来,可以形成一个顺序:

先用 DDD 问:这是 ChatBI 的业务概念吗? 再用 DDD 问:这条规则属于哪个业务对象? 然后用 COLA 问:这段代码应该放在哪一层? 最后用 COLA 问:依赖方向有没有反过来?

这比直接照抄目录更重要。

三、ChatBI 案例:从胖 Service 到 DDD + COLA

我们用“用户提问生成数据分析回答”作为例子。

需求是:

用户输入自然语言问题。 系统识别问题意图。 选择可用数据集。 解析指标和维度。 检查数据权限。 生成 SQL。 校验 SQL 安全性。 执行查询。 生成图表和文字解释。 保存会话记录。

如果写成一个胖 Service,短期最快。但这个场景的复杂度会持续增长,所以必须先区分业务规则和技术实现。

DDD 先看业务。

用户问“最近 30 天华东区 GMV 环比变化怎么样”,系统至少要理解:

最近 30 天:时间范围 华东区:筛选条件 GMV:指标 环比变化:分析意图 怎么样:回答形式

这不是简单字符串处理,而是 ChatBI 的核心业务。

因此可以建模为:

Question:用户原始问题 QueryIntent:查询意图 Metric:指标 Dimension:维度 TimeRange:时间范围 Dataset:数据集 SemanticModel:语义模型 DataPermission:数据权限 SqlDraft:待校验 SQL Answer:最终回答

其中,Metric不是数据库字段的别名。它应该表达业务口径。

比如 GMV:

指标名:GMV 业务含义:成交总额 计算口径:sum(pay_amount) 可用数据集:order_summary 默认时间字段:pay_time 权限约束:按组织和数据域过滤

这就是 DDD 的价值:把“GMV”从一个 SQL 片段提升为业务概念。

接着,Domain 不应该直接依赖大模型、数仓或向量库。它定义自己需要的能力:

public interface IntentGateway { QueryIntent recognize(Question question, SemanticModel semanticModel); } public interface SqlGenerationGateway { SqlDraft generate(QueryPlan queryPlan); } public interface WarehouseGateway { QueryResult query(SqlDraft sql); }

这些接口放在 Domain,是因为 Domain 要表达“我需要识别意图、生成 SQL、查询数据”。具体用哪个模型、哪个数仓、哪个 SDK,是 Infrastructure 的事。

COLA 之后可以这样组织:

client AskQuestionCmd ChatAnswerDTO adapter ChatController app AskQuestionAppService domain chat Question Conversation Answer semantic SemanticModel Metric Dimension TimeRange dataset Dataset DatasetSelector security DataPermission PermissionPolicy query QueryIntent QueryPlan SqlDraft SqlSafetyPolicy gateway IntentGateway SqlGenerationGateway WarehouseGateway AuditGateway infrastructure llm IntentGatewayImpl SqlGenerationGatewayImpl warehouse WarehouseGatewayImpl audit AuditGatewayImpl repository ConversationRepositoryImpl

App 层只编排一次问答流程:

public ChatAnswerDTO ask(AskQuestionCmd cmd) { Question question = Question.of(cmd.getQuestion()); UserId userId = new UserId(cmd.getUserId()); SemanticModel model = semanticModelRepository.getDefault(); QueryIntent intent = intentGateway.recognize(question, model); Dataset dataset = datasetSelector.select(intent, model); permissionPolicy.check(userId, dataset, intent); QueryPlan plan = queryPlanner.plan(intent, dataset, model); SqlDraft sql = sqlGenerationGateway.generate(plan); sqlSafetyPolicy.check(sql); QueryResult result = warehouseGateway.query(sql); Answer answer = answerFactory.create(question, intent, result); conversationRepository.save(question, answer); auditGateway.record(userId, dataset, sql); return chatAnswerAssembler.toDTO(answer); }

这段代码仍然能看出完整流程,但它不承载所有规则。

比如 SQL 安全规则可以放在 Domain:

public class SqlSafetyPolicy { public void check(SqlDraft sql) { if (!sql.isSelectOnly()) { throw new BizException("只允许查询语句"); } if (sql.hasUnsafeFunction()) { throw new BizException("SQL 包含高风险函数"); } if (!sql.hasLimit()) { throw new BizException("查询必须限制返回行数"); } } }

指标口径也可以是领域对象:

public class Metric { private final MetricCode code; private final String expression; private final DatasetId datasetId; public boolean belongsTo(Dataset dataset) { return this.datasetId.equals(dataset.id()); } }

LLM 调用留在 Infrastructure:

public class SqlGenerationGatewayImpl implements SqlGenerationGateway { public SqlDraft generate(QueryPlan plan) { String prompt = promptTemplate.render(plan); String sql = llmClient.generate(prompt); return SqlDraft.of(sql); } }

这里的重点是:Prompt、模型 SDK、供应商参数没有进入 Domain。Domain 只知道自己需要一个SqlDraft

这样拆完后,变化会被隔离。

模型从 OpenAI 换成通义千问,主要改:

SqlGenerationGatewayImpl IntentGatewayImpl

GMV 口径变化,主要改:

Metric SemanticModel

SQL 安全规则变化,主要改:

SqlSafetyPolicy

数仓从 Hive 换成 ClickHouse,主要改:

WarehouseGatewayImpl

前端接口参数变化,主要改:

ChatController AskQuestionCmd

这就是 DDD + COLA 的组合价值:业务规则回到业务模型,技术变化关进基础设施层。

四、回到架构思维:控制变化,而不是堆架构

学 DDD 和 COLA,最终不是为了背概念,而是训练判断力。

第一步是分类。

看到 ChatBI 里一段代码,先问它属于哪类职责:

它是在接收外部请求吗? 它是在编排一次问答流程吗? 它是在表达指标、权限、SQL 安全等业务规则吗? 它是在调用 LLM、数仓、向量库、审计系统吗?

对应到 COLA:

Adapter:入口 App:流程 Domain:规则 Infrastructure:技术实现

如果 Controller 里开始拼 Prompt,这是分类错误。
如果 Domain 里直接调用 LLM SDK,这是分类错误。
如果 AppService 里写满指标口径判断,这是分类错误。
如果 Infrastructure 决定“用户能不能看这个指标”,也是分类错误。

第二步是建模。

ChatBI 里最容易混淆的是:把技术对象当业务对象。

ChatRequest不是领域模型。
SqlDTO不是领域模型。
TableDO不是领域模型。
PromptTemplate也不一定是领域模型。

真正值得建模的,是那些稳定的业务概念:

指标 维度 数据集 语义模型 查询意图 数据权限 SQL 安全策略 会话 回答

判断标准很简单:

业务人员会不会说这个词? 数据产品会不会维护它? 它有没有规则? 它是否会因为业务变化而变化?

如果答案是肯定的,它才值得进入 Domain。

第三步是划边界。

ChatBI 的变化来源很多,边界不清就会迅速失控。

入口变化挡在 Adapter。 问答流程变化挡在 App。 指标、权限、语义、SQL 安全规则变化挡在 Domain。 LLM、数仓、向量库、审计系统变化挡在 Infrastructure。

比如模型供应商变化,不应该影响指标口径。
数仓 SQL 方言变化,不应该影响用户问题建模。
权限系统接口变化,不应该影响QuestionMetric
前端展示变化,不应该影响 SQL 安全策略。

边界的意义不是让文件变多,而是让变化停在该停的位置。

第四步是保持克制。

不是所有 ChatBI 能力都要完整 DDD。

如果只是一个内部 Demo:用户输入问题,直接拼 Prompt,生成 SQL,查库返回结果,用简单结构就够了。

但如果系统已经出现这些特征,就值得引入 DDD + COLA:

指标口径经常变化 权限规则复杂 数据集很多 多模型、多数仓并存 SQL 安全要求高 问答链路需要审计 多个团队共同维护语义层

反过来,如果只是简单报表查询、一次性验证、短期 PoC,就不要硬造聚合、领域事件和复杂网关。

架构不是越重越好。成熟的判断是:

复杂度在哪里,就在哪里建模。 变化从哪里来,就在哪里设边界。 没有复杂度,就不要制造复杂度。

结语

ChatBI 不是简单的“调用大模型生成 SQL”。真正难的是把自然语言、指标口径、语义模型、数据权限、SQL 安全和查询执行组织成一个可演进的系统。

DDD 和 COLA 合在一起,给出了一条清晰路径:

用 DDD 识别 ChatBI 的业务概念。 用 DDD 判断规则属于谁。 用 COLA 安放入口、流程、规则和技术实现。 用 COLA 控制依赖方向。

一句话概括:

用 DDD 看清 ChatBI 的业务,用 COLA 放好 ChatBI 的代码。

好的架构不是目录漂亮,也不是概念堆满,而是变化发生时,你知道该改哪里,也知道哪里不该被影响。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/10 2:53:56

网络安全入门指南:从零开始构建安全防护意识

1. 引言&#xff1a;为什么网络安全如此重要&#xff1f; 在万物互联的智能时代&#xff0c;网络安全已从专业领域演变为全民必修课。无论是个人数字资产保护&#xff0c;还是企业核心数据防护&#xff0c;乃至国家关键信息基础设施安全&#xff0c;网络安全的影响无处不在。 …

作者头像 李华
网站建设 2026/7/10 2:53:29

多元杭州尽显风华

古韵新姿&#xff0c;多元杭州尽显风华江南自古是文人墨客向往之地&#xff0c;其中杭州更被誉为“人间天堂”。这座始建于隋朝的城市&#xff0c;因西湖而闻名。唐朝诗人白居易曾在《钱塘湖春行》中写道“最爱湖东行不足&#xff0c;绿杨阴里白沙堤”。苏轼在宋神宗熙宁四年任…

作者头像 李华
网站建设 2026/7/10 2:53:22

OpenClaw 网关离线、文件被拦截?全套修复方案在这里

&#x1f50d;前言 OpenClaw&#xff08;圈内昵称“小龙虾”&#xff09;是一款备受瞩目的开源 AI 智能体项目&#xff0c;在 GitHub 上已累计获得超过 28 万星标。与常规的对话型 AI 不同&#xff0c;它能够理解自然语言指令并自动执行电脑本地操作&#xff0c;因此被许多职场…

作者头像 李华
网站建设 2026/7/10 2:52:56

ARM Cortex-A 系列演进分析:从 A5 到 A78 的 8 代架构性能跃迁

ARM Cortex-A 系列演进分析&#xff1a;从 A5 到 A78 的 8 代架构性能跃迁 在移动计算和嵌入式系统领域&#xff0c;ARM Cortex-A 系列处理器凭借其出色的能效比和持续演进的性能表现&#xff0c;已经成为智能手机、平板电脑乃至服务器市场的核心驱动力。本文将深入剖析从 Cort…

作者头像 李华
网站建设 2026/7/10 2:50:49

大数据毕设项目: 多渠道新闻爬虫采集与整合发布系统的设计与实现 基于网页数据抓取的新闻热点监测聚合系统(源码+文档,讲解、调试运行,定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/7/10 2:49:26

Python-dotenv 1.0.1 环境变量管理:3种配置方案与5个常见陷阱解析

Python-dotenv 1.0.1 环境变量管理&#xff1a;3种配置方案与5个常见陷阱解析在Python项目开发中&#xff0c;环境变量管理是连接代码与运行环境的桥梁。想象一下这样的场景&#xff1a;你的团队正在开发一个电商平台&#xff0c;本地开发环境使用SQLite数据库&#xff0c;测试…

作者头像 李华