惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Hackread – Cybersecurity News, Data Breaches, AI and More
W
WeLiveSecurity
C
Check Point Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Vulnerabilities – Threatpost
GbyAI
GbyAI
A
Arctic Wolf
NISL@THU
NISL@THU
N
Netflix TechBlog - Medium
The Register - Security
The Register - Security
M
MIT News - Artificial intelligence
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Microsoft Security Blog
Microsoft Security Blog
Cyberwarzone
Cyberwarzone
C
CERT Recently Published Vulnerability Notes
T
Tenable Blog
G
GRAHAM CLULEY
O
OpenAI News
S
Schneier on Security
Google Online Security Blog
Google Online Security Blog
Vercel News
Vercel News
宝玉的分享
宝玉的分享
Attack and Defense Labs
Attack and Defense Labs
T
The Blog of Author Tim Ferriss
量子位
aimingoo的专栏
aimingoo的专栏
The Cloudflare Blog
P
Privacy & Cybersecurity Law Blog
S
SegmentFault 最新的问题
MongoDB | Blog
MongoDB | Blog
Apple Machine Learning Research
Apple Machine Learning Research
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
L
LINUX DO - 热门话题
博客园_首页
F
Full Disclosure
Recent Commits to openclaw:main
Recent Commits to openclaw:main
D
Docker
U
Unit 42
A
About on SuperTechFans
博客园 - 司徒正美
Hacker News - Newest:
Hacker News - Newest: "LLM"
人人都是产品经理
人人都是产品经理
Application and Cybersecurity Blog
Application and Cybersecurity Blog
G
Google Developers Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
J
Java Code Geeks
云风的 BLOG
云风的 BLOG
Scott Helme
Scott Helme
TaoSecurity Blog
TaoSecurity Blog

博客园 - delphi中间件

领域服务与领域事件 限界上下文与统一语言 领域驱动 mqtt即时通讯 ActiveRecord ORM RAD(速成应用开发) unigui插件框架 工厂流水线式自动生产UNIGUI WEB软件 delphi cs\web一种统一的界面风格 - delphi中间件 - 博客园 动态生成unidbgrid 单据工厂 用json元数据填充模板 mormot2 ORM rest vs jsonrpc SSE技术详解:使用 HTTP 做服务端数据推送应用的技术 http持久连接 json-rpc 2.0 MCP服务器 RTTI对性能的影响 频繁地创建和销毁对象 TMultiPartFormData 雪花ID core.binary.pas TJSONToDataSetBridge TIcsMQTTServer 咏南WEB开发框架 unigui ajax交互 UnimList卡片显示 UnimTabPanel tabsheet在下面 unipagecontrol tabsheet在下面 unitreemenu自动显示滚动条 uniimbitbtn手机按钮一些设置
业务规则和模型
delphi中间件 · 2026-07-20 · via 博客园 - delphi中间件
  • • 贫血模型:对象只有数据(字段 + getter/setter),没有行为。业务逻辑全写在 Service 里。对象是个"数据袋子"。
  • • 充血模型:对象既有数据,也有操作这些数据的行为(业务方法)。业务逻辑写在对象自己身上。对象是个"会干活的人"。

类比:

  贫血 = 一份病历表(只记录数据)+ 一个医生(Service,所有诊断治疗都他干)。病历自己什么都不会。

  充血 = 一个真实的病人,他自己会发烧、会康复、会对药物产生反应。行为长在他身上。

贫血模型弊端:

  • 1. 规则没人守order.setStatus(5) 这行代码,任何地方都能调。哪天有个同事在别处写 order.setStatus(5) 而忘了检查"是否已发货",就把已发货订单取消了,数据直接出错。Order 自己毫无防御能力
  • 2. 规则会重复和漂移。"已发货不能取消"这条规则,取消接口写一遍、批量取消又写一遍、定时任务再写一遍,迟早不一致。
  • 3. 魔法数字满天飞status == 3setStatus(5),可读性极差,违背统一语言。
  • 4. 对象和行为分离,违反面向对象的封装原则。数据在 Order,操作数据的逻辑却在 OrderService,谈不上"对象"。

充血模型好处:

  • 1. 规则只有一个守门人。想取消订单?只能调 order.cancel(),而它内部强制检查规则。没有 setStatus,外部根本没法跳过检查直接改状态。规则无处可逃
  • 2. 规则只写一处。无论从哪取消订单,都走 order.cancel(),规则天然统一。
  • 3. 代码即业务order.cancel()order.pay() 直接对应业务语言(统一语言落地),自解释。
  • 4. 真正的面向对象:数据和操作数据的行为封装在一起。

为什么 DDD 推崇充血模型

一句话:充血模型让"业务规则"有了一个明确、唯一、无法绕过的家。

贫血模型的本质问题是——它把"数据"和"操作数据的规则"拆开了。规则一旦离开数据独自待在 Service 里,就失去了对数据的守护能力,谁都能绕过它直接 setXxx。系统一大,规则就会被无数个 Service 方法重复实现、各自漂移,最终腐烂成大泥球。

充血模型把规则塞回数据旁边,让对象自己守护自己的不变式(呼应第 06 章聚合根)。这是 DDD 战术设计的灵魂。