Value Object — Domain-Driven Designda identifikatori bilan emas, tarkibidagi qiymatlar bilan aniqlanadigan obyekt turidir. Ikki value object barcha muhim qiymatlari bo‘yicha teng bo‘lsa, ular bir xil ma’noni bildiradi. Pul miqdori, sana oralig‘i, koordinata yoki manzil domen talabiga qarab value object sifatida modellashtirilishi mumkin.
Qiymat bo‘yicha tenglik
Money obyektida amount va currency mavjud bo‘lsin. 100 UZS qiymatli ikki alohida instance domen nuqtayi nazaridan tengdir. Ularning xotira manzili yoki database row identifikatori muhim emas. 100 UZS va 100 USD esa soni teng bo‘lsa ham boshqa qiymat hisoblanadi.
Equality hisobida qaysi maydonlar qatnashishi modelda ochiq belgilanadi. Formatlash uchun berilgan locale yoki cache kabi texnik maydon qiymat semantikasiga kirmasligi mumkin. Hash qiymati equality bilan mos bo‘lishi shart, aks holda set va map kabi collectionlarda obyekt noto‘g‘ri ishlaydi.
O‘zgarmaslik
Value Object odatda immutable qilinadi. Qiymatni o‘zgartirish mavjud instance maydonini almashtirish emas, yangi obyekt yaratish orqali bajariladi. DateRange kengaytirilsa, avvalgi intervalni o‘zgartirmaydigan yangi DateRange qaytariladi. Bu sharing va parallel bajarishda yashirin yon ta’sirlarni kamaytiradi.
Immutable model constructor yoki factory paytida invariantni tekshiradi. Masalan, interval boshlanishi tugashidan keyin bo‘la olmaydi, pul valyutasi esa tanilgan kod bo‘lishi kerak. Noto‘g‘ri value object umuman yaratilmasa, keyingi metodlar har safar bir xil tekshiruvni takrorlamaydi.
Domen xatti-harakati
Value Object faqat maydonlar to‘plami emas. Money.add boshqa Moneyni qabul qilib, valyutalar mosligini tekshirishi va yangi natija qaytarishi mumkin. EmailAddress normalizatsiya va format tekshiruvini o‘zida saqlaydi. Shu tariqa primitive obsession, ya’ni barcha domen qiymatini oddiy string yoki son bilan ifodalash kamayadi.
Har string uchun alohida class yaratish talab qilinmaydi. Value Object domen qoidasi, birlik, format yoki ko‘p joyda takrorlanuvchi semantika mavjud bo‘lganda foyda beradi. Faqat bir joyda ko‘rinadigan, qoidasiz matnni murakkab modelga aylantirish ortiqcha bo‘lishi mumkin.
Entity tarkibidagi o‘rni
Entity value objectlarni atribut sifatida saqlashi mumkin. Customerning Address qiymati almashtirilganda customer identity o‘zgarmaydi. OrderLine narx va miqdor value objectlaridan total hisoblaydi. Value object boshqa aggregatega xavfsiz nusxalanishi mumkin, chunki u tashqi identity va yashirin mutable holatga ega emas.
Value Objectning o‘zi lifecyclega ega bo‘lmasa-da, uning eski qiymati audit yoki eventda saqlanishi mumkin. Entity manzili yangilanganda AddressChanged eventiga avvalgi va yangi immutable qiymatlar yozilishi tarixni aniq ko‘rsatadi.
Saqlash usullari
Relational bazada value object ustunlar guruhiga flatten qilinishi, JSON sifatida saqlanishi yoki ayrim hollarda alohida jadvalga mapping qilinishi mumkin. Alohida jadval texnik primary keyga ega bo‘lsa ham bu avtomatik ravishda uni domen Entityga aylantirmaydi. Domen identiteti persistence identifikatoridan farq qiladi.
ORM owned type yoki composite mapping orqali value objectni entity bilan birga saqlaydi. Query, indeks va migratsiya talablari format tanloviga ta’sir qiladi. Serialization paytida invariantni chetlab o‘tib, noto‘g‘ri obyekt yaratmaslik uchun deserializer factory yoki tekshiruvli constructorni ishlatadi.
Versiyalash
Value Object formati API yoki eventga chiqarilsa, uning maydonlari contractga aylanadi. Yangi birlik yoki majburiy maydon qo‘shish eski consumerlarni buzishi mumkin. O‘zgarish backward-compatible format, versiyalangan event yoki aniq migratsiya bilan joriy etiladi.
Bog‘liq tushunchalar
Domain-Driven Design, Entity, Immutability, Aggregate, Invariant, Primitive obsession, Equality