IlmHamroh
Python kursi/Arxitektura8/12-dars19 daqiqa
Mundarija (22)

27.8-dars: Domain-Driven Design kirish

27-QISM — ARXITEKTURA · 8-dars


1. Kirish va motivatsiya

Murakkab biznes tizimlarida eng qiyin qism texnologiya emas — biznesni tushunish: bank, sug'urta, logistika qoidalari chalkash, atamalar noaniq, dasturchi va biznes eksperti turli tilda gaplashadi. Natijada kod biznesga mos kelmaydi (dasturchi noto'g'ri tushungan), o'zgartirish qiyin (biznes tili va kod tili boshqacha). Domain-Driven Design (DDD) — murakkab biznes domenini kod bilan modellashtirish yondashuvi: biznes ekspertlari va dasturchilar umumiy til da gaplashadi, kod shu tilni aks ettiradi. DDD — texnik naqsh emas, balki biznesni kod bilan bog'lash falsafasi.

Domain-Driven Design (Eric Evans) — domen (biznes sohasi) ni markazga qo'yadigan dizayn yondashuvi. Asosiy tushunchalar: Ubiquitous Language (umumiy til — biznes va kod bir atama), Bounded Context (chegaralangan kontekst — domenning aniq chegarali qismi), Entity (o'ziga xoslik bilan obyekt — ID bilan), Value Object (qiymat obyekti — o'ziga xosliksiz, qiymati bilan), Aggregate (agregat — birgalikda o'zgaradigan obyektlar guruhi). DDD Clean Architecture 27.7-bob bilan uyg'un: domen markazda, boy modellar. Bu strategik (kontekstlar, til) va taktik (entity, value object) qismlarga bo'linadi. DDD — biznesni kod tiliga aylantirish.

Real vaziyat. Bir logistika loyihasida "yuk" so'zi turli bo'limda turli ma'no anglatardi — sotuvda "buyurtma", omborda "qadoq", yetkazishda "jo'natma". Kod chalkash edi (bir Yuk sinfi hammasini qamrab olmoqchi). DDD qo'llanildi: har bo'lim alohida bounded context (Sotuv, Ombor, Yetkazish), har birida o'z modeli va tili. Chegaralar aniqlandi, kod har kontekstda ravshan bo'ldi. DDD — chalkashlikni kontekstlarga bo'ldi.

Bu darsda Domain-Driven Design asoslarini o'rganamiz.

Bu darsda:

  • DDD nima
  • Ubiquitous Language (umumiy til)
  • Bounded Context (chegaralangan kontekst)
  • Entity va Value Object
  • Aggregate (agregat)
  • Strategik va taktik dizayn
  • DDD qachon kerak
  • Amaliy: domen modeli

ℹ Misollar sof Python bilan domen modellarini ko'rsatadi — deterministik.


2. Nazariya — chuqur tushuntirish

2.1. DDD nima

Biznes domenini kod bilan modellashtirish:

Biznes domeni (bank, logistika) — murakkab, chalkash
DDD: biznes eksperti + dasturchi = umumiy til
Kod domenni aks ettiradi (biznes tilida)

Domain-Driven Design (DDD) — murakkab biznes domenini (soha — bank, sug'urta, logistika) kod bilan modellashtirish yondashuvi: markazda biznes tushunchasi (texnologiya emas), biznes ekspertlari va dasturchilar birga model quradi (umumiy til). Sabab: murakkab tizimda eng qiyin qism biznesni to'g'ri tushunish (chalkash qoidalar, noaniq atamalar) — DDD buni tartibga soladi (til, chegaralar, modellar). DDD texnik naqsh emas — falsafa (biznesni kodga bog'lash). DDD — domenni birinchi o'ringa qo'yish.

2.2. Ubiquitous Language (umumiy til)

Biznes va kod bir atama:

python
# biznes: "buyurtma tasdiqlandi"
# kod: order.confirm()  (bir xil so'z)

class Buyurtma:
    def tasdiqla(self): ...      # biznes atamasi
    def bekor_qil(self): ...     # biznes atamasi
# kod biznes tilida (tarjima yo'q)

Ubiquitous Language (umumiy/hamma joyda ishlatiladigan til) — biznes ekspertlari va dasturchilar bir xil atamalar ni ishlatishi: biznes "buyurtma tasdiqlash" desa, kodda buyurtma.tasdiqla() (bir so'z). Sabab: agar til boshqacha bo'lsa (biznes "mijoz", kod "user") — tarjima kerak (yo'qotish, xato, tushunmovchilik); umumiy til — muloqot aniq (biznes kodni o'qiy oladi, dasturchi biznesni tushunadi). Til model, hujjat, kodda bir xil. Ubiquitous Language — biznes va texnika ko'prigi. Bir til — bir tushuncha.

2.3. Bounded Context (chegaralangan kontekst)

Domenning aniq chegarali qismi:

Katta domen → kichik kontekstlar (chegara bilan)
Sotuv konteksti:  "Mijoz" = xaridor
Qo'llab kontekst: "Mijoz" = ariza beruvchi
   har kontekstda o'z modeli, o'z tili

Bounded Context (chegaralangan kontekst) — katta domenni aniq chegarali kichik qismlarga bo'lish, har birida o'z modeli va tili: "Mijoz" Sotuv kontekstida "xaridor", Qo'llab-quvvatlash kontekstida "ariza beruvchi" — bir so'z, turli model. Sabab: katta domenda bir model hammasini qamrab olmaydi (bir Mijoz sinfi barcha bo'lim uchun — shishadi, chalkashadi); kontekstlarga bo'lish — har biri sodda, aniq. Kontekstlar orasida aniq chegara (xarita — context map). Bounded Context — domenni mazmunli qismlarga bo'lish. Chegara — model aniqligi.

2.4. Entity va Value Object

Ikki xil domen obyekti:

python
# Entity — o'ziga xoslik (ID) bilan
class Mijoz:
    def __init__(self, id, ism): self.id = id  # ID muhim
    # ikki mijoz — turli (ID farqli), ism o'zgarsa ham bir mijoz

# Value Object — qiymati bilan (ID yo'q)
class Pul:
    def __init__(self, miqdor, valyuta): ...
    # ikki Pul teng agar miqdor+valyuta teng (o'zgarmas)

Entity va Value Object — ikki xil domen obyekti: Entity — o'ziga xoslik (identity — ID) bilan (mijoz, buyurtma — ID muhim; ismi o'zgarsa ham bir mijoz, ikki mijoz turli ID); Value Object — qiymati bilan (pul, manzil, sana — ID yo'q; ikki Pul teng agar miqdor+valyuta teng), odatda o'zgarmas (immutable). Farq: Entity "kim/qaysi" (ID bo'yicha), Value Object "nima" (qiymat bo'yicha). Value object — sodda, xavfsiz (o'zgarmas), tenglik qiymatga. Entity — hayot davomida kuzatiladigan (ID), Value — almashtiriladigan qiymat.

2.5. Aggregate (agregat)

Birgalikda o'zgaradigan guruh:

python
# Aggregate — bir butun (ildiz orqali kirish)
class Buyurtma:                    # aggregate root
    def __init__(self): self.qatorlar = []
    def qator_qosh(self, m, soni):  # ichki obyektlarni boshqaradi
        self.qatorlar.append(BuyurtmaQatori(m, soni))
    # tashqi kod faqat Buyurtma orqali (qatorlarga to'g'ridan emas)

Aggregate (agregat) — birgalikda o'zgaradigan va bir butun sifatida ishlanadigan obyektlar guruhi, aggregate root (ildiz) orqali kiriladi: Buyurtma (root) va uning qatorlar (ichki) — tashqi kod faqat Buyurtma bilan ishlaydi (qatorlarga to'g'ridan emas). Sabab: agregat izchillik chegarasi (invariant — qoida: "buyurtma summasi qatorlar yig'indisi" — ildiz ta'minlaydi); ildiz orqali kirish — qoidalar buzilmaydi. Bir tranzaksiyada bir agregat o'zgaradi. Aggregate — izchillik birligi (bir butun, ildiz orqali). Ildiz qoidani himoya qiladi.

2.6. Strategik va taktik dizayn

DDD ikki darajada: Strategik dizayn — katta rasm (domenni bounded context larga bo'lish, kontekst xaritasi, ubiquitous language — biznes bilan hamkorlik); Taktik dizayn — kod ichida (entity, value object, aggregate, repository, domain service — modelni qurish). Strategik — muhimroq (noto'g'ri chegara — butun tizim chalkash), taktik — amalga oshirish. Ko'p loyiha taktikaga (kod naqshlari) sho'ng'iydi, lekin strategik (kontekstlar, til) asosiy qiymat. DDD — biznes bilan birga model qurish (dasturchi yolg'iz emas). Strategik — nima/qayerda, taktik — qanday.

2.7. DDD qachon kerak

DDD narx talab qiladi (biznes bilan hamkorlik, modellashtirish, o'rganish) — har loyihaga emas: kerak — murakkab biznes domeni (bank, sug'urta, logistika — qoidalar chalkash, muhim); kerak emas — oddiy CRUD (ma'lumot kiritish-chiqarish, murakkab qoida yo'q — DDD ortiqcha). Belgi: agar biznes qoidalari murakkab va tizimning asosiy qiymati bo'lsa — DDD; agar texnik jihat asosiy bo'lsa (yuqori yuk, oddiy mantiq) — DDD keraksiz. DDD — murakkab domenga kuchli, oddiyga ortiqcha (KISS). Muvozanat: domen murakkabligiga qarab. DDD — murakkab biznes uchun vosita.

2.8. DDD — biznes va kod birligi

DDD asosiy g'oyasi — biznes va kod birligi: kod biznesni to'g'ridan-to'g'ri aks ettiradi (umumiy til), tarjima yo'qotishisiz. Bu Clean Architecture (27.7 — domen markazda) bilan uyg'un: DDD domen mazmunini (nima modellashtirish), Clean domen joyini (markazda, mustaqil) beradi — birga boy, himoyalangan domen. DDD murakkablikni boshqaradi: strategik (kontekstlar) katta rasmni, taktik (entity, aggregate) kodni. Katta, murakkab, uzoq yashaydigan biznes tizimlari uchun kuchli. DDD dasturchi va biznesni bir jamoaga aylantiradi (birga model quradi). DDD — biznesni kod bilan chuqur bog'lash. Kod biznes tilida — tizim tushunarli.


3. Tez ma'lumotnoma

python
# UBIQUITOUS LANGUAGE — biznes = kod atamasi
class Buyurtma:
    def tasdiqla(self): ...     # biznes so'zi

# BOUNDED CONTEXT — domen qismlari (o'z modeli)
# Sotuv: Mijoz=xaridor | Qo'llab: Mijoz=ariza beruvchi

# ENTITY — ID bilan (o'ziga xoslik)
class Mijoz:
    def __init__(self, id, ism): self.id = id  # ID muhim

# VALUE OBJECT — qiymat bilan (ID yo'q, o'zgarmas)
from dataclasses import dataclass
@dataclass(frozen=True)
class Pul:
    miqdor: float
    valyuta: str

# AGGREGATE — ildiz orqali (izchillik chegarasi)
class Buyurtma:                 # aggregate root
    def qator_qosh(self, m, n): ...   # ichkini boshqaradi

# STRATEGIK: kontekstlar, til | TAKTIK: entity, aggregate

DDD xulosasi

Ubiquitous Language — biznes va kod bir atama (tarjimasiz)
Bounded Context — domen qismlari (o'z modeli, chegara)
Entity — ID bilan (o'ziga xoslik) · Value Object — qiymat (o'zgarmas)
Aggregate — ildiz orqali (izchillik chegarasi)
Strategik (kontekst, til) + Taktik (entity, aggregate)
Murakkab biznes uchun (oddiy CRUD ga ortiqcha)

4. Batafsil misollar

Misollar sof Python bilan domen modellarini ko'rsatadi — deterministik.

Misol 1 — Value Object (o'zgarmas, qiymat tengligi)

python
"""Value Object: qiymati bilan teng, o'zgarmas (Pul misoli)."""
from dataclasses import dataclass


@dataclass(frozen=True)   # o'zgarmas (immutable)
class Pul:
    miqdor: float
    valyuta: str

    def qosh(self, boshqa: "Pul") -> "Pul":
        if self.valyuta != boshqa.valyuta:
            raise ValueError("Turli valyuta qo'shilmaydi")
        # yangi obyekt qaytaradi (o'zgarmas)
        return Pul(self.miqdor + boshqa.miqdor, self.valyuta)


def main() -> None:
    print("=== 1. Qiymat tengligi (ID yo'q) ===")
    a = Pul(100, "UZS")
    b = Pul(100, "UZS")
    print(f"  Pul(100,UZS) == Pul(100,UZS): {a == b}")

    print("\n=== 2. Turli qiymat — teng emas ===")
    c = Pul(200, "UZS")
    print(f"  a == c: {a == c}")

    print("\n=== 3. Qo'shish (yangi obyekt) ===")
    yigindi = a.qosh(c)
    print(f"  100 + 200 = {yigindi.miqdor} {yigindi.valyuta}")
    print(f"  asl a o'zgarmadi: {a.miqdor}")

    print("\n=== 4. O'zgarmaslik (frozen) ===")
    try:
        a.miqdor = 500   # xato — frozen
    except Exception as e:
        print(f"  o'zgartirib bo'lmaydi: {type(e).__name__}")
    print("  Value Object — qiymat bilan teng, o'zgarmas")
    print("  ⭐ Value Object — qiymat (ID yo'q)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Qiymat tengligi (ID yo'q) ===
  Pul(100,UZS) == Pul(100,UZS): True

=== 2. Turli qiymat — teng emas ===
  a == c: False

=== 3. Qo'shish (yangi obyekt) ===
  100 + 200 = 300 UZS
  asl a o'zgarmadi: 100

=== 4. O'zgarmaslik (frozen) ===
  o'zgartirib bo'lmaydi: FrozenInstanceError
  Value Object — qiymat bilan teng, o'zgarmas
  ⭐ Value Object — qiymat (ID yo'q)

Nima ko'rsatdi: 2.4-bo'lim.

Misol 2 — Entity (ID bilan o'ziga xoslik)

python
"""Entity: o'ziga xoslik (ID) bilan — ism o'zgarsa ham bir obyekt."""


class Mijoz:
    def __init__(self, mijoz_id: int, ism: str) -> None:
        self.mijoz_id = mijoz_id   # o'ziga xoslik
        self.ism = ism

    def ism_ozgartir(self, yangi_ism: str) -> None:
        self.ism = yangi_ism       # ID o'zgarmaydi

    def __eq__(self, boshqa: object) -> bool:
        # tenglik ID bo'yicha (qiymat emas)
        if not isinstance(boshqa, Mijoz):
            return False
        return self.mijoz_id == boshqa.mijoz_id


def main() -> None:
    print("=== 1. Ikki mijoz — turli ID ===")
    ali = Mijoz(1, "Ali")
    vali = Mijoz(2, "Vali")
    print(f"  ali == vali: {ali == vali}")

    print("\n=== 2. Ism o'zgardi — bir mijoz ===")
    ali_eski = Mijoz(1, "Ali")
    ali.ism_ozgartir("Alisher")
    print(f"  ism: {ali.ism}")
    print(f"  ali (ID=1) == ali_eski (ID=1): {ali == ali_eski}")

    print("\n=== 3. Tenglik ID bo'yicha (qiymat emas) ===")
    print("  ism farqli, lekin ID bir xil → teng")

    print("\n=== 4. Entity vs Value Object ===")
    print("  Entity: ID bilan (Mijoz — kim)")
    print("  Value: qiymat bilan (Pul — nima)")
    print("  ⭐ Entity — o'ziga xoslik (ID)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Ikki mijoz — turli ID ===
  ali == vali: False

=== 2. Ism o'zgardi — bir mijoz ===
  ism: Alisher
  ali (ID=1) == ali_eski (ID=1): True

=== 3. Tenglik ID bo'yicha (qiymat emas) ===
  ism farqli, lekin ID bir xil → teng

=== 4. Entity vs Value Object ===
  Entity: ID bilan (Mijoz — kim)
  Value: qiymat bilan (Pul — nima)
  ⭐ Entity — o'ziga xoslik (ID)

Nima ko'rsatdi: 2.4-bo'lim.

Misol 3 — Aggregate (ildiz izchillikni himoya qiladi)

python
"""Aggregate: ildiz (Buyurtma) ichki qatorlarni va qoidani boshqaradi."""
from dataclasses import dataclass


@dataclass(frozen=True)
class BuyurtmaQatori:
    mahsulot: str
    narx: float
    soni: int

    def jami(self) -> float:
        return self.narx * self.soni


class Buyurtma:
    """Aggregate root — ildiz orqali kiriladi."""

    def __init__(self) -> None:
        self._qatorlar: list = []   # ichki (himoyalangan)

    def qator_qosh(self, mahsulot: str, narx: float, soni: int) -> None:
        # biznes qoidasi: soni musbat
        if soni <= 0:
            raise ValueError("Soni musbat bo'lishi kerak")
        self._qatorlar.append(BuyurtmaQatori(mahsulot, narx, soni))

    def umumiy_summa(self) -> float:
        # izchillik: summa qatorlar yig'indisi (ildiz ta'minlaydi)
        return sum(q.jami() for q in self._qatorlar)

    def qatorlar_soni(self) -> int:
        return len(self._qatorlar)


def main() -> None:
    buyurtma = Buyurtma()

    print("=== 1. Qatorlar qo'shish (ildiz orqali) ===")
    buyurtma.qator_qosh("Python kursi", 100, 2)
    buyurtma.qator_qosh("Go kursi", 120, 1)
    print(f"  qatorlar soni: {buyurtma.qatorlar_soni()}")

    print("\n=== 2. Umumiy summa (izchillik) ===")
    print(f"  jami: {buyurtma.umumiy_summa()}")

    print("\n=== 3. Biznes qoidasi (ildiz himoya qiladi) ===")
    try:
        buyurtma.qator_qosh("Xato", 50, 0)
    except ValueError as e:
        print(f"  {e}")

    print("\n=== 4. Ildiz orqali kirish ===")
    print("  tashqi kod faqat Buyurtma bilan")
    print("  qatorlar himoyalangan (qoida buzilmaydi)")
    print("  ⭐ Aggregate — izchillik chegarasi (ildiz)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Qatorlar qo'shish (ildiz orqali) ===
  qatorlar soni: 2

=== 2. Umumiy summa (izchillik) ===
  jami: 320

=== 3. Biznes qoidasi (ildiz himoya qiladi) ===
  Soni musbat bo'lishi kerak

=== 4. Ildiz orqali kirish ===
  tashqi kod faqat Buyurtma bilan
  qatorlar himoyalangan (qoida buzilmaydi)
  ⭐ Aggregate — izchillik chegarasi (ildiz)

Nima ko'rsatdi: 2.5-bo'lim.

Misol 4 — Bounded Context (bir so'z, turli model)

python
"""Bounded Context: 'Mahsulot' Sotuv va Ombor kontekstida turli model."""


# --- SOTUV konteksti ---
class SotuvMahsuloti:
    """Sotuvda muhim: narx, chegirma."""

    def __init__(self, nom: str, narx: float) -> None:
        self.nom = nom
        self.narx = narx

    def chegirmali(self, foiz: float) -> float:
        return round(self.narx * (1 - foiz / 100), 2)


# --- OMBOR konteksti ---
class OmborMahsuloti:
    """Omborda muhim: joylashuv, miqdor."""

    def __init__(self, nom: str, miqdor: int, javon: str) -> None:
        self.nom = nom
        self.miqdor = miqdor
        self.javon = javon

    def yetarlimi(self, kerak: int) -> bool:
        return self.miqdor >= kerak


def main() -> None:
    print("=== 1. Sotuv konteksti (narx muhim) ===")
    sotuv = SotuvMahsuloti("Python kursi", 1000)
    print(f"  {sotuv.nom}: narx {sotuv.narx}")
    print(f"  20% chegirma: {sotuv.chegirmali(20)}")

    print("\n=== 2. Ombor konteksti (miqdor muhim) ===")
    ombor = OmborMahsuloti("Python kursi", 50, "A-12")
    print(f"  {ombor.nom}: {ombor.miqdor} dona, javon {ombor.javon}")
    print(f"  30 ta yetarlimi: {ombor.yetarlimi(30)}")

    print("\n=== 3. Bir 'Mahsulot' — ikki model ===")
    print("  Sotuvda: narx, chegirma")
    print("  Omborda: miqdor, joylashuv")

    print("\n=== 4. Kontekst chegarasi ===")
    print("  har kontekst o'z modeli (bir sinf hammasi emas)")
    print("  chegara — model aniq va sodda")
    print("  ⭐ Bounded Context — bir so'z, turli model")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Sotuv konteksti (narx muhim) ===
  Python kursi: narx 1000
  20% chegirma: 800.0

=== 2. Ombor konteksti (miqdor muhim) ===
  Python kursi: 50 dona, javon A-12
  30 ta yetarlimi: True

=== 3. Bir 'Mahsulot' — ikki model ===
  Sotuvda: narx, chegirma
  Omborda: miqdor, joylashuv

=== 4. Kontekst chegarasi ===
  har kontekst o'z modeli (bir sinf hammasi emas)
  chegara — model aniq va sodda
  ⭐ Bounded Context — bir so'z, turli model

Nima ko'rsatdi: 2.3-bo'lim.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"DDD — texnik naqsh" Biznesni modellashtirish falsafasi
"Bir model hammasiga" Bounded context (turli model)
"Entity = Value Object" ID vs qiymat
"Value Object o'zgaradi" O'zgarmas (immutable)
"Agregat — oddiy guruh" Izchillik chegarasi (ildiz)
"DDD har loyihaga" Murakkab biznes uchun
"Til — dasturchi ishi" Biznes bilan umumiy
"Taktik muhimroq" Strategik (kontekst) asosiy

6. Keng tarqalgan xatolar va yechimlari

1. Bir katta model (barcha kontekst)

python
class Mijoz: # 50 maydon (barcha bo'lim)      # ⚠️
# har bounded context o'z Mijoz modeli        # ✅

2. Value Object o'zgaruvchan

python
class Pul: def ozgartir(self)                 # ⚠️
@dataclass(frozen=True) class Pul             # ✅ o'zgarmas

3. Entity tengligi qiymat bo'yicha

python
# ism teng → mijoz teng                        # ⚠️
# ID teng → mijoz teng (o'ziga xoslik)          # ✅

4. Agregat ichkiga to'g'ridan kirish

python
buyurtma._qatorlar.append(...)                # ⚠️
buyurtma.qator_qosh(...)  # ildiz orqali       # ✅

5. Kod tili biznesdan farqli

python
class User: def do_action()  # texnik          # ⚠️
class Mijoz: def buyurtma_ber()  # biznes tili  # ✅

6. DDD oddiy CRUD ga

python
# oddiy jadval CRUD ga aggregate, context     # ⚠️
# oddiy — sodda model (KISS)                    # ✅

7. Til hujjatda, kodda boshqacha

python
# hujjat "buyurtma", kod "order_record"        # ⚠️
# bir til (hujjat, model, kod)                  # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 27.7-dars (o'tilgan): Clean Architecture — domen markazda
  • 27.9-dars: Mikroservis — bounded context = xizmat
  • 27.11-dars: Event Sourcing — domen hodisalari
  • 16-qism (o'tilgan): OOP — entity, value object
  • 23-qism (o'tilgan): ORM — repository (agregat saqlash)

8. Eng yaxshi amaliyotlar

  1. Umumiy til (biznes = kod atamasi).

  2. Bounded context (har biri o'z modeli).

  3. Value Object — o'zgarmas (frozen).

  4. Entity — ID bo'yicha tenglik.

  5. Agregat — ildiz orqali (izchillik).

  6. Strategik avval (kontekst, til).

  7. DDD — murakkab biznesga (KISS — oddiyga sodda).

  8. Biznes bilan birga model qur.


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # DDD nima?
2.  # DDD texnik naqshmi?
3.  # ubiquitous language nima?
4.  # nega umumiy til?
5.  # bounded context nima?
6.  # bir model hammasigami?
7.  # entity nima?
8.  # value object nima?
9.  # entity vs value?
10. # aggregate nima?
11. # aggregate root nima?
12. # DDD qachon kerak?
Javoblar
  1. Biznes domenini kod bilan modellashtirish
  2. Yo'q — falsafa (biznesni bog'lash)
  3. Biznes va kod bir atama
  4. Tarjimasiz muloqot (aniq)
  5. Domenning chegarali qismi (o'z modeli)
  6. Yo'q — har kontekst o'z modeli
  7. ID bilan obyekt (o'ziga xoslik)
  8. Qiymat bilan obyekt (ID yo'q, o'zgarmas)
  9. ID (kim) vs qiymat (nima)
  10. Birgalikda o'zgaradigan guruh
  11. Agregatga kirish nuqtasi (ildiz)
  12. Murakkab biznes domenida

Vazifa 2: Xatolarni tuzating

python
1.  class Mijoz: # 50 maydon        # bounded context

2.  class Pul: def ozgartir         # frozen

3.  # ism teng → mijoz teng          # ID bo'yicha

4.  buyurtma._qatorlar.append()     # ildiz orqali

5.  # oddiy CRUD ga aggregate        # KISS
Javoblar
python
1.  har kontekst o'z Mijoz modeli

2.  @dataclass(frozen=True) class Pul

3.  ID teng → mijoz teng

4.  buyurtma.qator_qosh(...)

5.  oddiy — sodda model

Vazifa 3: Value Object

Tuzing:

  1. frozen=True
  2. Qiymat tengligi
  3. O'zgarmas
  4. Manzil/Pul

Vazifa 4: Entity

Tuzing:

  1. ID
  2. __eq__ (ID)
  3. O'zgaruvchan holat
  4. Mijoz

Vazifa 5: Aggregate

Tuzing:

  1. Ildiz
  2. Ichki obyektlar
  3. Qoida
  4. Kirish nuqtasi

Vazifa 6: Bounded Context

Tuzing:

  1. Kontekst 1
  2. Kontekst 2
  3. Turli model
  4. Chegara

Vazifa 7: O'ylash

DDD ning eng qiyin va eng qimmatli qismi — ubiquitous language (biznes va dasturchi bir tilda gaplashishi). Nima uchun "til" (atamalar) shunchalik muhim (u shunchaki so'z emas), va nega biznes ekspertlari va dasturchilar odatda turli tilda gaplashadi — bu "tarjima" muammosi qanday qilib xatolarga va noto'g'ri tizimlarga olib keladi?

Javob

Qisqa javob: "Til" muhim, chunki: til — tushuncha (atama ortida model, qoida, ma'no turadi — "buyurtma" so'zi biznes qoidalarini olib yuradi); noaniq yoki turli til — noaniq tushuncha (dasturchi "buyurtma" ni noto'g'ri tushunadi — noto'g'ri kod). Til shunchaki so'z emas — u fikrlash vositasi (til orqali domen modellashtiriladi). Biznes va dasturchilar turli tilda gaplashadi, chunki: turli dunyo (biznes — soha atamalari: "polisa", "anderrayting"; dasturchi — texnik: "record", "process"), turli maqsad (biznes — qoidalar, dasturchi — amalga oshirish), oraliq shaxs (ko'pincha biznes → tahlilchi → dasturchi — har uzatishda ma'no yo'qoladi). "Tarjima" muammosi xatolarga olib keladi, chunki: har tarjima — yo'qotish (biznes "mijoz kreditga loyiq" deydi → dasturchi "if balance > 0" deb tushunadi — soddalashtirdi, qoidani yo'qotdi), noaniqlik (bir so'z ikki ma'no — dasturchi bittasini tanlaydi, ehtimol noto'g'ri), yashirin farq (kod biznesdan sekin uzoqlashadi — har o'zgarish tarjima, farq to'planadi — oxirida kod biznesga mos kelmaydi). Umumiy til bu tarjimani yo'q qiladi: biznes va kod bir so'z — yo'qotish yo'q, biznes kodni o'qiy oladi (tekshiradi), dasturchi biznesni tushunadi (to'g'ri model). Bu qiyin, chunki: biznes atamalarini o'rganish (dasturchi domenni o'rganishi kerak — vaqt), atamalarni kelishish (biznes bilan muzokara — "buni nima deymiz?"), izchil ishlatish (kod, hujjat, gap — bir so'z — intizom). Muhandislik saboqlari: kod — biznesning aks-sadosi (mos kelishi kerak); til — model (atama ortida tushuncha); tarjima — yo'qotish (har uzatishda); umumiy til — biznes va texnika ko'prigi (qiyin, lekin eng qimmatli).

1. Nega til muhim

Til — tushuncha (atama ortida model, qoida). Noaniq til — noaniq tushuncha (noto'g'ri kod). Til — fikrlash vositasi.

2. Nega turli tilda

  • Turli dunyo (soha vs texnik atama)
  • Turli maqsad (qoida vs amalga oshirish)
  • Oraliq shaxs (har uzatishda yo'qotish)

3. Tarjima muammosi

Muammo Natija
Yo'qotish Qoida soddalashadi (yo'qoladi)
Noaniqlik Noto'g'ri ma'no tanlanadi
Yashirin farq Kod biznesdan uzoqlashadi

4. Umumiy til yechadi

Biznes = kod so'z. Yo'qotish yo'q, biznes kodni tekshiradi, dasturchi biznesni tushunadi.

5. Muhandislik saboqlari

  1. Kod — biznes aks-sadosi (mos kelsin)
  2. Til — model (atama = tushuncha)
  3. Tarjima — yo'qotish (har uzatish)
  4. Umumiy til — ko'prik (qiyin, qimmatli)

6. Xulosa

  1. Til — tushuncha (shunchaki so'z emas)
  2. Turli dunyo → turli til → tarjima
  3. Tarjima — yo'qotish, noaniqlik, farq
  4. Umumiy til — biznes va kod birligi

Nimani mustahkamlaydi: 2.2, 2.8-bo'limlar.


Xulosa

Bu darsda Domain-Driven Design asoslarini o'rgandik.

Eng muhim uch fikr:

  1. DDD va Ubiquitous Language. Domain-Driven Design — murakkab biznes domenini kod bilan modellashtirish yondashuvi: markazda biznes tushunchasi (texnologiya emas), biznes ekspertlari va dasturchilar birga model quradi; texnik naqsh emas — falsafa (biznesni kodga bog'lash). Ubiquitous Language (umumiy til) — biznes va dasturchilar bir xil atamalar ni ishlatadi (biznes "buyurtma tasdiqlash" → kod buyurtma.tasdiqla()): til boshqacha bo'lsa — tarjima (yo'qotish, xato); umumiy til — aniq muloqot (biznes kodni o'qiydi, dasturchi biznesni tushunadi). Til model, hujjat, kodda bir xil.

  2. Bounded Context, Entity, Value Object, Aggregate. Bounded Context — katta domenni aniq chegarali qismlarga bo'lish, har birida o'z modeli va tili ("Mijoz" Sotuvda "xaridor", Qo'llabda "ariza beruvchi"): bir model hammasini qamramaydi (shishadi). Entity — o'ziga xoslik (ID) bilan (mijoz — ism o'zgarsa ham bir mijoz, tenglik ID bo'yicha); Value Object — qiymati bilan (pul, manzil — ID yo'q, tenglik qiymatga, o'zgarmas immutable). Aggregate — birgalikda o'zgaradigan guruh, aggregate root (ildiz) orqali kiriladi (Buyurtma va qatorlar — ildiz izchillikni/invariantni himoya qiladi, tashqi kod faqat ildiz bilan).

  3. Strategik/taktik va biznes-kod birligi. DDD ikki darajada: strategik (katta rasm — bounded context, kontekst xaritasi, ubiquitous language — biznes bilan hamkorlik) va taktik (kod — entity, value object, aggregate, repository); strategik muhimroq (noto'g'ri chegara — butun tizim chalkash). DDD narx talab qiladi — murakkab biznes domeni uchun (bank, sug'urta, logistika); oddiy CRUD ga ortiqcha (KISS). Asosiy g'oya — biznes va kod birligi: kod biznesni to'g'ridan aks ettiradi (til — tushuncha, tarjima — yo'qotish; umumiy til biznes-texnika ko'prigi). DDD Clean Architecture (27.7 — domen markazda) bilan uyg'un (DDD — mazmun, Clean — joy) va mikroservis (27.9 — bounded context = xizmat) uchun asos. Kod biznes tilida — tizim tushunarli.

Keyingi darsda monolit va mikroservis arxitekturalarini o'rganamiz: tizimni bitta yaxlit dastur (monolit) yoki ko'p mustaqil xizmat (mikroservis) sifatida qurish — ularning afzalliklari, kamchiliklari va qachon qaysi birini tanlash.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
27.8-dars: Domain-Driven Design kirish — IlmHamroh