<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>貧血模型 on Tarragon</title><link>https://tarrragon.github.io/blog/tags/%E8%B2%A7%E8%A1%80%E6%A8%A1%E5%9E%8B/</link><description>Recent content in 貧血模型 on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Fri, 10 Jul 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/%E8%B2%A7%E8%A1%80%E6%A8%A1%E5%9E%8B/index.xml" rel="self" type="application/rss+xml"/><item><title>Data Bag</title><link>https://tarrragon.github.io/blog/ddd/knowledge-cards/data-bag/</link><pubDate>Fri, 10 Jul 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/ddd/knowledge-cards/data-bag/</guid><description>&lt;p>資料袋承擔資料的搬運與呈現：DTO、API model、UI state、設定物件。它的特徵是任何欄位組合都是合法狀態——修改其中一欄、其餘欄位的意義照舊成立。因為組合全部合法、逐欄位覆寫工具（copyWith、setter、builder）在資料袋上語意清晰、沒有代價。DDD 社群常用「貧血模型（anemic model）」指沒有行為的資料容器——語意接近、但資料袋是正確形態而非缺陷，判定依&lt;a href="https://tarrragon.github.io/blog/ddd/knowledge-cards/invariant/" data-link-title="Invariant" data-link-desc="領域模型的約束規則落在哪一層時使用。不變式是在物件整個生命週期都必須為真的業務規則——狀態只能沿流程轉換、被同一條規則綁住的欄位必須一起換。">不變式&lt;/a>有無而定。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>資料袋跟領域模型是型別類別的兩端。判準是「有沒有不允許任意組合的欄位」——有就是領域模型、沒有就是資料袋。資料袋裡照樣可以放語意封閉的 &lt;a href="https://tarrragon.github.io/blog/ddd/knowledge-cards/value-object/" data-link-title="Value Object" data-link-desc="判斷一個概念該用內容比對還是身份追蹤時使用。value object 的同一性由內容定義——內容相等就是同一個、替換實例對系統沒有影響。">value object&lt;/a>（如 Money）；容器的類別判定跟欄位的封閉性是正交的兩條軸。資料袋可以隨業務演進升級成領域模型——升級時機由演化訊號決定、而非預測。&lt;/p>
&lt;h2 id="可觀察訊號">可觀察訊號&lt;/h2>
&lt;p>型別的每個欄位都可以獨立修改且不影響其餘欄位的語意——資料袋。型別上出現「請用某方法修改」的註解但欄位仍全部 public 可寫——判定可能錯了、讀 &lt;a href="https://tarrragon.github.io/blog/ddd/data-bag-vs-domain-model/" data-link-title="資料袋與領域模型" data-link-desc="判斷一個型別該是一袋欄位還是有行為的領域模型：判準是「有沒有不允許任意組合的欄位」。含判準用錯時規則退化成建議的機制、以及資料袋起步後升級的演化訊號。">資料袋與領域模型&lt;/a> 重新檢視。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>資料袋加上領域模型的儀式（工廠、私有建構、變更方法）只會製造沒有規則可守的 boilerplate。判斷準則是「這個型別有沒有需要強制的規則」——沒有就不要建領域模型。完整判準見 &lt;a href="https://tarrragon.github.io/blog/ddd/data-bag-vs-domain-model/" data-link-title="資料袋與領域模型" data-link-desc="判斷一個型別該是一袋欄位還是有行為的領域模型：判準是「有沒有不允許任意組合的欄位」。含判準用錯時規則退化成建議的機制、以及資料袋起步後升級的演化訊號。">資料袋與領域模型&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>資料袋承擔資料的搬運與呈現：DTO、API model、UI state、設定物件。它的特徵是任何欄位組合都是合法狀態——修改其中一欄、其餘欄位的意義照舊成立。因為組合全部合法、逐欄位覆寫工具（copyWith、setter、builder）在資料袋上語意清晰、沒有代價。DDD 社群常用「貧血模型（anemic model）」指沒有行為的資料容器——語意接近、但資料袋是正確形態而非缺陷，判定依<a href="/blog/ddd/knowledge-cards/invariant/" data-link-title="Invariant" data-link-desc="領域模型的約束規則落在哪一層時使用。不變式是在物件整個生命週期都必須為真的業務規則——狀態只能沿流程轉換、被同一條規則綁住的欄位必須一起換。">不變式</a>有無而定。</p>
<h2 id="概念位置">概念位置</h2>
<p>資料袋跟領域模型是型別類別的兩端。判準是「有沒有不允許任意組合的欄位」——有就是領域模型、沒有就是資料袋。資料袋裡照樣可以放語意封閉的 <a href="/blog/ddd/knowledge-cards/value-object/" data-link-title="Value Object" data-link-desc="判斷一個概念該用內容比對還是身份追蹤時使用。value object 的同一性由內容定義——內容相等就是同一個、替換實例對系統沒有影響。">value object</a>（如 Money）；容器的類別判定跟欄位的封閉性是正交的兩條軸。資料袋可以隨業務演進升級成領域模型——升級時機由演化訊號決定、而非預測。</p>
<h2 id="可觀察訊號">可觀察訊號</h2>
<p>型別的每個欄位都可以獨立修改且不影響其餘欄位的語意——資料袋。型別上出現「請用某方法修改」的註解但欄位仍全部 public 可寫——判定可能錯了、讀 <a href="/blog/ddd/data-bag-vs-domain-model/" data-link-title="資料袋與領域模型" data-link-desc="判斷一個型別該是一袋欄位還是有行為的領域模型：判準是「有沒有不允許任意組合的欄位」。含判準用錯時規則退化成建議的機制、以及資料袋起步後升級的演化訊號。">資料袋與領域模型</a> 重新檢視。</p>
<h2 id="設計責任">設計責任</h2>
<p>資料袋加上領域模型的儀式（工廠、私有建構、變更方法）只會製造沒有規則可守的 boilerplate。判斷準則是「這個型別有沒有需要強制的規則」——沒有就不要建領域模型。完整判準見 <a href="/blog/ddd/data-bag-vs-domain-model/" data-link-title="資料袋與領域模型" data-link-desc="判斷一個型別該是一袋欄位還是有行為的領域模型：判準是「有沒有不允許任意組合的欄位」。含判準用錯時規則退化成建議的機制、以及資料袋起步後升級的演化訊號。">資料袋與領域模型</a>。</p>
]]></content:encoded></item></channel></rss>