📌Domain Driven Design : Value Object
مفهوم Value Object یکی از مهمترین Building Blockهایی است که توسط Eric Evans در کتاب معروفش Domain-Driven Design: Tackling Complexity in the Heart of Software معرفی شد؛ مفهومی که اگر درست درک شود، میتواند ساختار Domain Model شما را بهشدت سادهتر، Maintainableتر و Expressiveتر کند.
💡ءValue Object چیست؟
در DDD، همه چیز در Domain یا Identity دارد یا فقط Value است.
یک Value Object:
🔹 هویتی (Identity) ندارد
🔹 فقط با مقدارش (Value) تعریف میشود
🔹 ءImmutable است
🔹 قابل جایگزینی است بدون اینکه معنی Domain تغییر کند
به بیان ساده:
اگر دو Object از نظر مقدار برابر باشند، در Domain یکی محسوب میشوند.
مثال:
📍 Address
💰 Money
📏 Distance
در Domain، مهم نیست کدام Address instance را داریم؛ اگر مقدارشان برابر باشد، از نظر Business یکی هستند.
🆚 Entity vs Value Object
📌Entity :
• دارای Identity
• ءMutable
• ءLifecycle دارد
• مقایسه با Id
• قابل Track شدن
📌 Value Object :
• بدون Identity
• ءImmutable
• ءLifecycle ندارد
• مقایسه با Value
• ءReplaceable
مثال:
Customer → Entity
CustomerEmail → Value Object
در دامین، Email هویت ندارد؛ فقط مقدار آن مهم است.
🔒 Immutability در Value Object
طبق تعریف Evans:
"Value Object should be immutable"
چرا؟چون اگر مقدار تغییر کند، دیگر همان مفهوم قبلی نیست.
مثال:
public sealed class Email
{
public string Value { get; }
public Email(string value)
{
if(string.IsNullOrWhiteSpace(value))
throw new ArgumentException("Email is required");
Value = value;
}
}
اگر Email تغییر کند:
یعنی یک Email جدید ساختهایم،
نه اینکه Email قبلی تغییر کرده باشد.
⚖️ Equality بر اساس Value
ءValue Objectها باید بر اساس مقدارشان مقایسه شوند نه Reference.
public override bool Equals(object? obj)
{
if (obj is not Email other)
return false;
return Value == other.Value;
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
در Domain:
new Email("a@gmail.com") == new Email("a@gmail.com")باید True باشد حتی اگر دو Instance متفاوت باشند.
🎯 چه زمانی از Value Object استفاده کنیم؟
وقتی:
✅ ءObject مفهوم Domain دارد
✅ ءIdentity ندارد
✅ فقط با مقدار تعریف میشود
✅ قابل تغییر نیست
✅ ءLifecycle مستقل ندارد
🚫 ءAnti-Pattern رایج
بسیاری از پروژهها این اشتباه را انجام میدهند:
public string Email { get; set; }در حالی که:
ءEmail یک Primitive نیست
بلکه یک Concept در Domain است.
این همان Primitive Obsession است که DDD سعی دارد از آن جلوگیری کند.
🧠 مزایای استفاده از Value Object
✔️ جلوگیری از Invalid State
✔️ افزایش Expressiveness در Domain Model
✔️ کاهش Coupling
✔️ ءEncapsulation بهتر Business Ruleها
✔️ جلوگیری از Primitive Obsession
✔️ تستپذیری بیشتر
✅ جمعبندی
ءValue Objectها کمک میکنند:
🔹️ءDomain شما Richتر شود
🔸️ءBusiness Ruleها نزدیک به Data تعریف شوند
🔹️ءModel شما از Primitive Typeها جدا شود
🔸️و مهمتر از همه، زبان Ubiquitous Language در کد منعکس شود
اگر در Domain چیزی Identity ندارد،
احتمالاً باید یک Value Object باشد.
🔖هشتگها:
#DDD #ValueObject #DomainModel