IlmHamroh
Python kursi/Arxitektura4/12-dars17 daqiqa
Mundarija (22)

27.4-dars: Dizayn naqshlari — strukturaviy (structural)

27-QISM — ARXITEKTURA · 4-dars


1. Kirish va motivatsiya

Katta tizim ko'p qismdan iborat: sizning kodingiz, tashqi kutubxonalar, eski modullar, boshqa xizmatlar. Bu qismlar bir-biriga mos kelmaydi (interfeys boshqacha), yoki to'g'ridan-to'g'ri bog'lash noqulay (murakkab, xavfli). Har safar bog'lanishni noldan o'ylash — chalkashlik. Strukturaviy naqshlar — obyektlar va sinflarni qanday bog'lash haqidagi sinalgan yechimlar: mos kelmaydigan qismlarni moslashtirish, murakkabligini yashirish, xulqni o'rash. Ular mavjud qismlardan katta tuzilma quradi — buzmasdan.

Strukturaviy naqshlar (structural patterns) — sinflar va obyektlarni birlashtirishni tartibga soladi: Adapter (moslashtirgich — mos kelmaydigan interfeysni moslash), Decorator (bezovchi — obyektga xulq qo'shish, o'ramasdan), Facade (fasad — murakkab tizimga oddiy yuz), Proxy (vakil — obyektga nazorat qatlami), Composite (kompozit — daraxt tuzilma, qism va butun bir xil). Bu naqshlar bog'liqlikni boshqaradi: qismlarni ajratadi, moslashtiradi, yashiradi. Ular SOLID ni 27.2-bob qo'llaydi: kichik interfeys (ISP), abstraksiya (DIP), kengaytirish (OCP). Strukturaviy naqshlar — qismlarni birlashtirish san'ati.

Real vaziyat. Bir loyihada eski to'lov tizimi charge(amount) metodini, yangi API esa process_payment(sum) ni kutardi — kod ikkalasini ishlata olmasdi. Adapter yozildi: YangiAdapter eski tizimni o'rab, yangi interfeysni taqdim etdi (process_payment → ichida charge). Kod endi ikkalasini bir xil ishlatadi. Eski kod tegilmadi, yangi kod moslashdi. Adapter — ikki dunyoni bog'lovchi ko'prik.

Bu darsda strukturaviy dizayn naqshlarini o'rganamiz.

Bu darsda:

  • Strukturaviy naqsh nima
  • Adapter (moslashtirgich)
  • Decorator (bezovchi)
  • Facade (fasad)
  • Proxy (vakil)
  • Composite (kompozit)
  • Strukturaviy naqshlar va bog'liqlik
  • Amaliy: naqsh qo'llash

ℹ Misollar sof Python bilan — deterministik.


2. Nazariya — chuqur tushuntirish

2.1. Strukturaviy naqsh nima

Qismlarni bog'lash:

Qismlar (kod, kutubxona, xizmat) → qanday bog'lash?
Strukturaviy: moslashtirish, o'rash, yashirish
Mavjud qismdan katta tuzilma (buzmasdan)

Strukturaviy naqsh — sinflar va obyektlarni birlashtirish (bog'lash) haqidagi sinalgan yechim: qismlar (kodingiz, kutubxonalar, xizmatlar) qanday mos keladi, o'raladi, yashiriladi. Maqsad: mavjud qismlardan katta, moslashuvchan tuzilma qurish — ularni o'zgartirmasdan. Yaratuvchi naqsh 27.3-bob obyekt tug'ilishini, strukturaviy — obyektlar bog'lanishini boshqaradi. Foydali: mos kelmaydigan interfeys (Adapter), murakkablik (Facade), xulq qo'shish (Decorator). Strukturaviy naqsh — bog'lanish yechimi.

2.2. Adapter (moslashtirgich)

Mos kelmaydigan interfeysni moslash:

python
# eski: charge(amount)
class EskiTolov:
    def charge(self, amount): return f"Eski: {amount}"

# yangi interfeys: process(sum)
class TolovAdapter:
    def __init__(self, eski): self.eski = eski
    def process(self, sum): return self.eski.charge(sum)  # moslash

Adapter (moslashtirgich) — bir sinfning interfeysini boshqa kutilgan interfeysga moslaydi: eski tizim charge(amount), yangi kod process(sum) kutadi — Adapter eskini o'rab, yangi interfeysni taqdim etadi. Sabab: mos kelmaydigan interfeyslar (eski kod, tashqi kutubxona, boshqa API) — ularni o'zgartirmasdan bog'lash. Analogiya: rozetka moslashtirgich (elektr vilkasi). Foydalanish: eski kod integratsiyasi, tashqi kutubxona o'rovi, interfeys birlashtirish. Adapter — ikki interfeys orasidagi tarjimon.

2.3. Decorator (bezovchi)

Obyektga xulq qo'shish:

python
# asosiy obyektni o'rab, xulq qo'shish
class Qahva:
    def narx(self): return 10
class Sut:                      # bezovchi
    def __init__(self, qahva): self.qahva = qahva
    def narx(self): return self.qahva.narx() + 2   # qo'shimcha
# Sut(Qahva()).narx() → 12

Decorator (bezovchi) — obyektni o'rab, unga yangi xulq/mas'uliyat qo'shadi (asl obyektni o'zgartirmasdan): Sut(Qahva()) — qahvaga sut qo'shadi (narx ortadi). Har bezovchi bir qatlam (Shakar(Sut(Qahva())) — ketma-ket). Sabab: xulqni dinamik qo'shish (meros — statik, bezovchi — ish vaqtida), ko'p kombinatsiya (meros bilan sinflar portlashi). Bu 12-qism dekoratorlaridan (@decorator) farqli, lekin bir g'oya (o'rash). Foydalanish: qo'shimcha (log, kesh, tekshirish), UI qatlamlar. Decorator — qatlam-qatlam xulq.

2.4. Facade (fasad)

Murakkab tizimga oddiy yuz:

python
# murakkab quyi tizimlar
class Cpu: def yukla(self): ...
class Xotira: def sozla(self): ...
class Disk: def oqi(self): ...

class Kompyuter:               # fasad
    def yoq(self):
        self.cpu.yukla(); self.xotira.sozla(); self.disk.oqi()
# mijoz: Kompyuter().yoq() — bitta oddiy chaqiruv

Facade (fasad) — murakkab quyi tizimga oddiy, yagona interfeys (yuz): mijoz murakkab qismlarni (CPU, xotira, disk) emas, bitta Kompyuter.yoq() ni ko'radi. Sabab: murakkab tizim (ko'p qism, tartib, bog'liqlik) — mijoz uchun yashirilishi kerak (u tafsilotni bilmasin). Fasad quyi tizimlarni birlashtirib, sodda API beradi. Analogiya: mashina kaliti (dvigatel tafsilotini bilmaysiz). Foydalanish: kutubxona o'rovi, murakkab ish oqimi, API soddalashtirish. Facade — murakkablikka oddiy eshik.

2.5. Proxy (vakil)

Obyektga nazorat qatlami:

python
class HaqiqiyRasm:
    def korsat(self): return "rasm"
class RasmProxy:               # vakil
    def __init__(self): self._haqiqiy = None
    def korsat(self):
        if self._haqiqiy is None:
            self._haqiqiy = HaqiqiyRasm()   # dangasa yuklash
        return self._haqiqiy.korsat()

Proxy (vakil/o'rinbosar) — asosiy obyektga nazorat qatlami (o'rinbosar): mijoz proxy bilan ishlaydi, proxy asosiyga yo'naltiradi — lekin oldin/keyin nazorat qo'shadi. Turlari: dangasa (lazy — asosiyni kerak bo'lganda yaratish), himoya (huquq tekshirish), kesh (natijani saqlash), uzoq (remote — tarmoq). Sabab: asosiy obyektga to'g'ridan-to'g'ri kirishni nazorat (qimmat yaratish, xavfsizlik, kesh). Decorator xulq qo'shadi, Proxy kirishni nazorat qiladi. Foydalanish: dangasa yuklash, kesh, huquq. Proxy — nazorat qiluvchi o'rinbosar.

2.6. Composite (kompozit)

Daraxt tuzilma — qism va butun bir xil:

python
class Fayl:
    def __init__(self, olcham): self.olcham = olcham
    def hajm(self): return self.olcham
class Papka:                   # kompozit
    def __init__(self): self.ichi = []
    def hajm(self): return sum(x.hajm() for x in self.ichi)
# papka ichida fayl va papka — bir xil hajm()

Composite (kompozit) — obyektlarni daraxt tuzilmasiga birlashtiradi, qism (fayl) va butun (papka) bir xil interfeys bilan ishlanadi: hajm() ham faylda, ham papkada (papka ichini yig'adi). Sabab: iyerarxik tuzilma (fayl tizimi, menyu, tashkilot) — mijoz qism yoki butunni ajratmasdan bir xil ishlatadi (rekursiv). Analogiya: papka ichida papka ichida fayl. Foydalanish: fayl tizimi, UI daraxti, tashkiliy tuzilma, ifoda daraxti. Composite — qism-butun birligi (rekursiv).

2.7. Strukturaviy naqshlar va bog'liqlik

Strukturaviy naqshlar bog'liqlikni boshqaradi: Adapter mos kelmaydiganni bog'laydi (ajratmasdan), Facade bog'liqlikni yashiradi (mijoz quyiga bog'lanmaydi), Proxy kirishni nazorat qiladi (qatlam), Decorator xulqni ajratadi (o'rash), Composite iyerarxiyani birlashtiradi. Umumiy g'oya: past bog'liqlik (loose coupling) — qismlar bir-biriga kam bog'liq (o'zgarish tarqalmaydi). Ular DIP (abstraksiya), ISP (kichik interfeys) ni qo'llaydi. Strukturaviy naqshlar — qismlarni ajratib bog'lash (mustaqillik). Past bog'liqlik — moslashuvchan tizim.

2.8. Strukturaviy naqshlar — tizim skeleti

Strukturaviy naqshlar tizimning skeletini (qismlar qanday turadi) shakllantiradi: Adapter chegaralarni (tashqi bilan), Facade qatlamlarni (murakkablikni yashirish — 27.6 qatlamli arxitektura), Proxy kesish nuqtalarini (nazorat), Composite iyerarxiyani. Katta tizimda (mikroservis — 27.9, qatlamlar — 27.6) bu naqshlar chegaralarni belgilaydi (qayerda tarjimon, qayerda yuz, qayerda nazorat). Ular yaratuvchi (27.3 — obyekt tug'iladi) va xulq-atvor (27.5 — obyekt ishlaydi) orasida: obyektlar bog'lanadi, keyin o'zaro ishlaydi. Strukturaviy naqshlar — tizim arxitekturasining karkasi. Skelet — qismlar qanday ushlab turiladi.


3. Tez ma'lumotnoma

python
# ADAPTER — interfeys moslash
class Adapter:
    def __init__(self, eski): self.eski = eski
    def yangi_metod(self): return self.eski.eski_metod()

# DECORATOR — xulq qo'shish (o'rash)
class Bezovchi:
    def __init__(self, obj): self.obj = obj
    def amal(self): return self.obj.amal() + qoshimcha

# FACADE — oddiy yuz
class Fasad:
    def bajar(self):
        self.a.x(); self.b.y(); self.c.z()   # murakkabni yashir

# PROXY — nazorat qatlami
class Proxy:
    def amal(self):
        # oldin: tekshir/kesh/dangasa
        return self.haqiqiy.amal()

# COMPOSITE — daraxt (qism = butun)
class Butun:
    def __init__(self): self.ichi = []
    def qiymat(self): return sum(x.qiymat() for x in self.ichi)

Strukturaviy naqshlar xulosasi

Adapter — interfeys moslash (tarjimon)
Decorator — xulq qo'shish (o'rash, qatlam)
Facade — murakkabga oddiy yuz
Proxy — kirish nazorati (dangasa, kesh, himoya)
Composite — daraxt (qism va butun bir xil)
Maqsad: past bog'liqlik (moslashuvchan)

4. Batafsil misollar

Misollar sof Python bilan — deterministik.

Misol 1 — Adapter: eski va yangi interfeys

python
"""Adapter: mos kelmaydigan interfeysni yangi interfeysga moslash."""


class EskiTolov:
    """Eski tizim — charge(amount) metodi."""

    def charge(self, amount: float) -> str:
        return f"Eski tizim: {amount} to'landi"


class YangiTolov:
    """Yangi tizim — process(summa) metodi."""

    def process(self, summa: float) -> str:
        return f"Yangi tizim: {summa} to'landi"


class TolovAdapter:
    """Eskini yangi interfeysga moslaydi."""

    def __init__(self, eski: EskiTolov) -> None:
        self.eski = eski

    def process(self, summa: float) -> str:
        # yangi 'process' → ichida eski 'charge'
        return self.eski.charge(summa)


def tolovni_amalga_oshir(tolov, summa: float) -> str:
    # bu funksiya 'process' interfeysini kutadi
    return tolov.process(summa)


def main() -> None:
    print("=== 1. Yangi tizim (to'g'ridan) ===")
    print(f"  {tolovni_amalga_oshir(YangiTolov(), 100)}")

    print("\n=== 2. Eski tizim — to'g'ridan ishlamaydi ===")
    print("  EskiTolov.process yo'q (charge bor)")

    print("\n=== 3. Adapter orqali eski tizim ===")
    adapter = TolovAdapter(EskiTolov())
    print(f"  {tolovni_amalga_oshir(adapter, 100)}")

    print("\n=== 4. Bir xil interfeys ===")
    print("  yangi va adapter — ikkalasi 'process'")
    print("  eski kod tegilmadi (moslashdi)")
    print("  ⭐ Adapter — interfeys tarjimoni")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Yangi tizim (to'g'ridan) ===
  Yangi tizim: 100 to'landi

=== 2. Eski tizim — to'g'ridan ishlamaydi ===
  EskiTolov.process yo'q (charge bor)

=== 3. Adapter orqali eski tizim ===
  Eski tizim: 100 to'landi

=== 4. Bir xil interfeys ===
  yangi va adapter — ikkalasi 'process'
  eski kod tegilmadi (moslashdi)
  ⭐ Adapter — interfeys tarjimoni

Nima ko'rsatdi: 2.2-bo'lim.

Misol 2 — Decorator: xulq qatlamlari

python
"""Decorator: obyektni o'rab, xulq qo'shish (ketma-ket qatlamlar)."""
from abc import ABC, abstractmethod


class Ichimlik(ABC):
    @abstractmethod
    def narx(self) -> int: ...

    @abstractmethod
    def tavsif(self) -> str: ...


class Qahva(Ichimlik):
    def narx(self) -> int:
        return 10

    def tavsif(self) -> str:
        return "qahva"


class Qoshimcha(Ichimlik):
    """Bezovchi asos — ichimlikni o'raydi."""

    def __init__(self, ichimlik: Ichimlik) -> None:
        self.ichimlik = ichimlik


class Sut(Qoshimcha):
    def narx(self) -> int:
        return self.ichimlik.narx() + 2

    def tavsif(self) -> str:
        return f"{self.ichimlik.tavsif()} + sut"


class Shakar(Qoshimcha):
    def narx(self) -> int:
        return self.ichimlik.narx() + 1

    def tavsif(self) -> str:
        return f"{self.ichimlik.tavsif()} + shakar"


def main() -> None:
    print("=== 1. Oddiy qahva ===")
    q = Qahva()
    print(f"  {q.tavsif()}: {q.narx()}")

    print("\n=== 2. Sut qo'shish (o'rash) ===")
    sutli = Sut(Qahva())
    print(f"  {sutli.tavsif()}: {sutli.narx()}")

    print("\n=== 3. Sut + shakar (ikki qatlam) ===")
    toliq = Shakar(Sut(Qahva()))
    print(f"  {toliq.tavsif()}: {toliq.narx()}")

    print("\n=== 4. Dinamik kombinatsiya ===")
    ikki_shakar = Shakar(Shakar(Qahva()))
    print(f"  {ikki_shakar.tavsif()}: {ikki_shakar.narx()}")
    print("  har qatlam narx qo'shadi (asl tegilmaydi)")
    print("  ⭐ Decorator — o'rab xulq qo'shish")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Oddiy qahva ===
  qahva: 10

=== 2. Sut qo'shish (o'rash) ===
  qahva + sut: 12

=== 3. Sut + shakar (ikki qatlam) ===
  qahva + sut + shakar: 13

=== 4. Dinamik kombinatsiya ===
  qahva + shakar + shakar: 12
  har qatlam narx qo'shadi (asl tegilmaydi)
  ⭐ Decorator — o'rab xulq qo'shish

Nima ko'rsatdi: 2.3-bo'lim.

Misol 3 — Facade: murakkablikka oddiy yuz

python
"""Facade: murakkab quyi tizimlarni bitta oddiy interfeys ostiga yashirish."""


class Cpu:
    def yukla(self) -> str:
        return "CPU yuklandi"


class Xotira:
    def sozla(self) -> str:
        return "Xotira sozlandi"


class Disk:
    def oqi(self) -> str:
        return "Disk o'qildi"


class KompyuterFasadi:
    """Murakkab quyi tizimlarga oddiy yuz."""

    def __init__(self) -> None:
        self.cpu = Cpu()
        self.xotira = Xotira()
        self.disk = Disk()

    def yoq(self) -> list:
        # murakkab tartibni yashiradi
        return [
            self.cpu.yukla(),
            self.xotira.sozla(),
            self.disk.oqi(),
            "Tayyor!",
        ]


def main() -> None:
    print("=== 1. Fasadsiz (mijoz hammasini biladi) ===")
    print("  cpu.yukla(); xotira.sozla(); disk.oqi() ...")
    print("  mijoz tartibni, tafsilotni bilishi kerak")

    print("\n=== 2. Fasad bilan (bitta chaqiruv) ===")
    kompyuter = KompyuterFasadi()
    for qadam in kompyuter.yoq():
        print(f"  {qadam}")

    print("\n=== 3. Mijoz oddiy ===")
    print("  KompyuterFasadi().yoq() — bitta metod")
    print("  quyi tizimlar yashirilgan")

    print("\n=== 4. Foyda ===")
    print("  mijoz murakkablikni bilmaydi (past bog'liqlik)")
    print("  quyi tizim o'zgarsa — fasad ichida (mijoz tegilmaydi)")
    print("  ⭐ Facade — murakkablikka oddiy eshik")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Fasadsiz (mijoz hammasini biladi) ===
  cpu.yukla(); xotira.sozla(); disk.oqi() ...
  mijoz tartibni, tafsilotni bilishi kerak

=== 2. Fasad bilan (bitta chaqiruv) ===
  CPU yuklandi
  Xotira sozlandi
  Disk o'qildi
  Tayyor!

=== 3. Mijoz oddiy ===
  KompyuterFasadi().yoq() — bitta metod
  quyi tizimlar yashirilgan

=== 4. Foyda ===
  mijoz murakkablikni bilmaydi (past bog'liqlik)
  quyi tizim o'zgarsa — fasad ichida (mijoz tegilmaydi)
  ⭐ Facade — murakkablikka oddiy eshik

Nima ko'rsatdi: 2.4-bo'lim.

Misol 4 — Composite: daraxt tuzilma

python
"""Composite: fayl (qism) va papka (butun) bir xil interfeys (hajm)."""
from abc import ABC, abstractmethod


class TizimElementi(ABC):
    @abstractmethod
    def hajm(self) -> int: ...

    @abstractmethod
    def korinish(self, chuqurlik: int = 0) -> str: ...


class Fayl(TizimElementi):
    def __init__(self, nom: str, olcham: int) -> None:
        self.nom = nom
        self.olcham = olcham

    def hajm(self) -> int:
        return self.olcham

    def korinish(self, chuqurlik: int = 0) -> str:
        return "  " * chuqurlik + f"{self.nom} ({self.olcham})"


class Papka(TizimElementi):
    def __init__(self, nom: str) -> None:
        self.nom = nom
        self.ichi: list = []

    def qosh(self, element: TizimElementi) -> None:
        self.ichi.append(element)

    def hajm(self) -> int:
        # ichidagi barchaning hajmi (rekursiv)
        return sum(e.hajm() for e in self.ichi)

    def korinish(self, chuqurlik: int = 0) -> str:
        satrlar = ["  " * chuqurlik + f"[{self.nom}] ({self.hajm()})"]
        for e in self.ichi:
            satrlar.append(e.korinish(chuqurlik + 1))
        return "\n".join(satrlar)


def main() -> None:
    ildiz = Papka("loyiha")
    ildiz.qosh(Fayl("main.py", 100))
    ildiz.qosh(Fayl("test.py", 50))

    src = Papka("src")
    src.qosh(Fayl("app.py", 200))
    src.qosh(Fayl("db.py", 150))
    ildiz.qosh(src)

    print("=== 1. Fayl hajmi ===")
    print(f"  main.py: {Fayl('main.py', 100).hajm()}")

    print("\n=== 2. Papka hajmi (rekursiv) ===")
    print(f"  src papka: {src.hajm()}")
    print(f"  ildiz (jami): {ildiz.hajm()}")

    print("\n=== 3. Daraxt ko'rinishi ===")
    print(ildiz.korinish())

    print("\n=== 4. Qism va butun bir xil ===")
    print("  fayl va papka — ikkalasi hajm()")
    print("  mijoz ajratmaydi (rekursiv)")
    print("  ⭐ Composite — qism-butun birligi (daraxt)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Fayl hajmi ===
  main.py: 100

=== 2. Papka hajmi (rekursiv) ===
  src papka: 350
  ildiz (jami): 500

=== 3. Daraxt ko'rinishi ===
[loyiha] (500)
  main.py (100)
  test.py (50)
  [src] (350)
    app.py (200)
    db.py (150)

=== 4. Qism va butun bir xil ===
  fayl va papka — ikkalasi hajm()
  mijoz ajratmaydi (rekursiv)
  ⭐ Composite — qism-butun birligi (daraxt)

Nima ko'rsatdi: 2.6-bo'lim.


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

Noto'g'ri fikr To'g'risi
"Adapter kodni o'zgartiradi" O'raydi (tegmasdan)
"Decorator = @dekorator" Bir g'oya, obyekt o'rovi
"Facade — keraksiz qatlam" Murakkablikni yashiradi
"Proxy = Decorator" Nazorat vs xulq
"Composite murakkab" Qism-butun bir xil
"Naqsh doim kerak" Muammo bo'lganda
"Bog'lanish muhim emas" Past bog'liqlik maqsad
"Meros = Decorator" Statik vs dinamik

6. Keng tarqalgan xatolar va yechimlari

1. Adapter o'rniga eski kodni o'zgartirish

python
# eski kodni yangi interfeysga o'zgartirish   # ⚠️ (xavf)
class Adapter: def yangi(self): self.eski.eski_metod()  # ✅

2. Decorator interfeysni buzadi

python
class Bezovchi:  # boshqa metodlar          # ⚠️
class Bezovchi(BirXilInterfeys)  # bir xil   # ✅

3. Facade hamma narsani qiladi (xudo)

python
class Fasad: # 50 metod                       # ⚠️
# faqat oddiy interfeys (asosiy amallar)       # ✅

4. Proxy va Decorator aralashtirish

python
# Proxy xulq qo'shmoqchi                       # ⚠️
# Proxy — nazorat, Decorator — xulq            # ✅

5. Composite da yaproq/tugun farqi buzildi

python
fayl.qosh(...)   # faylga qo'shish?           # ⚠️
# faqat Papka.qosh (Fayl — yaproq)             # ✅

6. Naqshni majburlash

python
# oddiy bog'lanishga 3 naqsh                   # ⚠️
# oddiy — to'g'ridan; naqsh — muammoga          # ✅

7. Chuqur o'rash (ko'p qatlam)

python
A(B(C(D(E(obj)))))   # o'qish qiyin           # ⚠️
# ma'noli qatlamlar (kerakli)                   # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 27.3-dars (o'tilgan): Yaratuvchi — obyekt tug'iladi
  • 27.5-dars: Xulq-atvor — obyekt ishlaydi
  • 27.6-dars: Qatlamli arxitektura — Facade, Adapter
  • 27.2-dars (o'tilgan): SOLID — DIP, ISP
  • 12-qism (o'tilgan): Dekoratorlar (@)

8. Eng yaxshi amaliyotlar

  1. Adapter — eskini o'ra (o'zgartirma).

  2. Decorator — bir interfeys (o'rash).

  3. Facade — oddiy yuz (xudo emas).

  4. Proxy — nazorat (dangasa, kesh, himoya).

  5. Composite — qism-butun bir interfeys.

  6. Past bog'liqlik (loose coupling).

  7. Naqsh — muammoga (majburlama).

  8. Chuqur o'rashdan saqlan (ravshan).


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # strukturaviy naqsh nima?
2.  # Adapter nima?
3.  # Adapter nima uchun?
4.  # Decorator nima?
5.  # Decorator vs meros?
6.  # Facade nima?
7.  # Facade foyda?
8.  # Proxy nima?
9.  # Proxy vs Decorator?
10. # Composite nima?
11. # Composite qayerda?
12. # past bog'liqlik nima?
Javoblar
  1. Obyektlarni bog'lash naqshlari
  2. Interfeysni moslash
  3. Mos kelmaydiganni bog'lash (tegmasdan)
  4. Obyektga xulq qo'shish (o'rash)
  5. Decorator dinamik, meros statik
  6. Murakkabga oddiy yuz
  7. Murakkablikni yashiradi
  8. Kirish nazorat qatlami
  9. Proxy nazorat, Decorator xulq
  10. Daraxt (qism-butun bir xil)
  11. Fayl tizimi, UI daraxti
  12. Qismlar kam bog'liq (loose)

Vazifa 2: Xatolarni tuzating

python
1.  # eski kodni o'zgartirish             # Adapter

2.  class Bezovchi: boshqa metod          # bir interfeys

3.  class Fasad: 50 metod                 # oddiy

4.  # Proxy xulq qo'shadi                 # nazorat

5.  fayl.qosh(...)                        # Papka.qosh
Javoblar
python
1.  Adapter (eskini moslash)

2.  class Bezovchi(BirXilInterfeys)

3.  faqat asosiy amallar (oddiy yuz)

4.  Proxy — nazorat (Decorator — xulq)

5.  faqat Papka.qosh (Fayl — yaproq)

Vazifa 3: Adapter

Tuzing:

  1. Eski interfeys
  2. Yangi interfeys
  3. Adapter
  4. O'rash

Vazifa 4: Decorator

Tuzing:

  1. Asos
  2. Bezovchi
  3. Qatlam
  4. Kombinatsiya

Vazifa 5: Facade

Tuzing:

  1. Quyi tizimlar
  2. Fasad
  3. Oddiy metod
  4. Yashirish

Vazifa 6: Composite

Tuzing:

  1. Yaproq
  2. Tugun
  3. Rekursiv
  4. Bir interfeys

Vazifa 7: O'ylash

Strukturaviy naqshlarning umumiy maqsadi — past bog'liqlik (qismlar bir-biriga kam bog'liq): Adapter chegara qo'yadi, Facade yashiradi, Proxy nazorat qiladi. Nima uchun "past bog'liqlik" katta tizimning eng muhim xususiyati (undan tezlik, xato emas), va nega "bog'liqlik" — arxitekturaning asosiy tashvishi (naqshlar, qatlamlar, mikroservislar — hammasi bog'liqlik haqida)?

Javob

Qisqa javob: "Past bog'liqlik" katta tizimning eng muhim xususiyati, chunki: bog'liqlik — o'zgarish tarqalishi (bir qism o'zgarsa, unga bog'liq qismlar ham o'zgaradi). Yuqori bog'liqlik (tight coupling) — bir o'zgarish butun tizimga to'lqin (bir joyni tuzatish o'nta joyni buzadi — mo'rt, qo'rqinchli); past bog'liqlik (loose) — o'zgarish mahalliy (bir qism o'zgaradi, boshqalar tegilmaydi — xavfsiz, tez). Katta tizimda (yuz minglab qator, ko'p jamoa) bog'liqlik — asosiy dushman: yuqori bog'liqlik tizimni qotiradi (o'zgartirish imkonsiz), past bog'liqlik moslashuvchan qiladi. Tezlik yoki xato emas — chunki ular ham bog'liqlikdan kelib chiqadi (mo'rt tizim sekin o'zgaradi, ko'p xato). "Bog'liqlik" arxitekturaning asosiy tashvishi, chunki: barcha arxitektura vositalari — bog'liqlikni boshqarish haqida: naqshlar (Adapter, Facade — bog'liqlikni ajratish), qatlamlar (27.6 — bir yo'nalishli bog'liqlik), interfeyslar (DIP — abstraksiyaga bog'lanish), mikroservislar (27.9 — mustaqil qismlar). Yaxshi arxitektura = to'g'ri bog'liqlik (kerakli joyda, kam, aniq). Yomon arxitektura = chalkash bog'liqlik ("spagetti" — hamma hammaga bog'liq, o'zgartirish imkonsiz). Muhandislik saboqlari: kod yozish oson, bog'liqlikni boshqarish qiyin; arxitektura — bog'liqlik san'ati (nima nimaga bog'liq, qanday, qayerda); past bog'liqlik — mustaqillik (qismlar alohida o'zgaradi, sinaladi, tushuniladi).

1. Bog'liqlik — o'zgarish tarqalishi

Bir qism o'zgarsa — bog'liqlar o'zgaradi. Yuqori: to'lqin (mo'rt). Past: mahalliy (xavfsiz).

2. Nega katta tizimda muhim

Bog'liqlik Natija
Yuqori (tight) Qotgan (o'zgartirish imkonsiz)
Past (loose) Moslashuvchan (mahalliy o'zgarish)

3. Hamma vosita bog'liqlik haqida

  • Naqshlar: bog'liqlikni ajratish
  • Qatlamlar: bir yo'nalishli
  • Interfeys (DIP): abstraksiyaga
  • Mikroservis: mustaqil qismlar

4. Yaxshi vs yomon arxitektura

Yaxshi = to'g'ri bog'liqlik (kam, aniq). Yomon = spagetti (hamma hammaga).

5. Muhandislik saboqlari

  1. Bog'liqlik — o'zgarish tarqalishi
  2. Past bog'liqlik — mahalliy o'zgarish (mustaqillik)
  3. Arxitektura — bog'liqlikni boshqarish
  4. Barcha vosita (naqsh, qatlam) shu haqda

6. Xulosa

  1. Bog'liqlik o'zgarishni tarqatadi
  2. Past bog'liqlik — moslashuvchan tizim
  3. Arxitektura = bog'liqlik san'ati
  4. Yaxshi = to'g'ri bog'liqlik (kam, aniq)

Nimani mustahkamlaydi: 2.7, 2.8-bo'limlar.


Xulosa

Bu darsda strukturaviy dizayn naqshlarini o'rgandik.

Eng muhim uch fikr:

  1. Strukturaviy naqsh, Adapter, Decorator. Strukturaviy naqsh — sinflar va obyektlarni birlashtirish (bog'lash) yechimi: mavjud qismlardan katta tuzilma qurish (ularni o'zgartirmasdan). Adapter (moslashtirgich) — bir interfeysni boshqa kutilgan interfeysga moslaydi (eski charge → yangi process); mos kelmaydiganni bog'laydi (tarjimon, eski kod tegilmaydi). Decorator (bezovchi) — obyektni o'rab, yangi xulq qo'shadi (asl o'zgarmaydi): Shakar(Sut(Qahva())) — qatlam-qatlam; dinamik (meros — statik), ko'p kombinatsiya.

  2. Facade, Proxy, Composite. Facade (fasad) — murakkab quyi tizimga oddiy, yagona interfeys (mijoz Kompyuter.yoq() ni ko'radi, CPU/xotira/disk emas); murakkablikni yashiradi (past bog'liqlik). Proxy (vakil) — asosiy obyektga nazorat qatlami (dangasa yuklash, kesh, himoya, uzoq); Decorator xulq qo'shadi, Proxy kirishni nazorat qiladi. Composite (kompozit) — obyektlarni daraxt tuzilmasiga, qism (fayl) va butun (papka) bir xil interfeys bilan (rekursiv hajm()); fayl tizimi, UI daraxti, iyerarxiya.

  3. Past bog'liqlik — arxitekturaning yuragi. Strukturaviy naqshlar bog'liqlikni boshqaradi: Adapter chegara qo'yadi, Facade yashiradi, Proxy nazorat qiladi, Decorator ajratadi, Composite birlashtiradi — umumiy g'oya past bog'liqlik (loose coupling: qismlar kam bog'liq, o'zgarish tarqalmaydi). Ular DIP, ISP ni qo'llaydi va tizim skeletini (qismlar qanday turadi) shakllantiradi. Bog'liqlik — o'zgarish tarqalishi: yuqori bog'liqlik tizimni qotiradi (bir o'zgarish to'lqin — mo'rt), past bog'liqlik moslashuvchan qiladi (mahalliy o'zgarish). Bog'liqlik — arxitekturaning asosiy tashvishi (naqshlar, qatlamlar — 27.6, mikroservislar — 27.9 — hammasi bog'liqlikni boshqaradi); yaxshi arxitektura = to'g'ri bog'liqlik (kam, aniq), yomon = spagetti. Strukturaviy naqshlar yaratuvchi 27.3-bob va xulq-atvor 27.5-bob orasida: obyektlar bog'lanadi, keyin ishlaydi.

Keyingi darsda xulq-atvor dizayn naqshlarini o'rganamiz: obyektlar bir-biri bilan qanday o'zaro ishlashi va mas'uliyat taqsimlashi haqidagi naqshlar (Strategy, Observer, Command, Iterator, State) — algoritm va aloqani moslashuvchan qilish.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!