Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. SOLID nima
- 2.2. S — Single Responsibility (bir mas'uliyat)
- 2.3. O — Open/Closed (ochiq/yopiq)
- 2.4. L — Liskov Substitution (almashinuv)
- 2.5. I — Interface Segregation (interfeys ajratish)
- 2.6. D — Dependency Inversion (bog'liqlik teskarisi)
- 2.7. SOLID birgalikda
- 2.8. SOLID — dizaynning maqsadi
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — SRP: mas'uliyatlarni ajratish
- Misol 2 — OCP: kengaytirishga ochiq
- Misol 3 — LSP: almashinuvchan vorislar
- Misol 4 — DIP: abstraksiyaga bog'lanish
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
27.2-dars: SOLID tamoyillari
27-QISM — ARXITEKTURA · 2-dars
1. Kirish va motivatsiya
Obyektga yo'naltirilgan kod (16-qism) yozish oson, lekin yaxshi yozish qiyin: sinflar shishib ketadi (hammasini qiladi), o'zgartirish bir joyni tuzatib boshqasini buzadi, yangi imkoniyat butun kodni qayta yozishni talab qiladi. SOLID — obyektga yo'naltirilgan dizaynning besh asosiy tamoyili: sinflarni moslashuvchan, kengaytiriladigan, sinaladigan qiladi. Har harf bir tamoyil: SRP, OCP, LSP, ISP, DIP. SOLID — toza kod 27.1-bob ni sinf/tizim darajasiga ko'taradi.
SOLID — Robert Martin umumlashtirgan besh tamoyil: S (Single Responsibility — bir mas'uliyat: sinf bir sababga o'zgaradi), O (Open/Closed — ochiq/yopiq: kengaytirishga ochiq, o'zgartirishga yopiq), L (Liskov Substitution — Liskov almashinuvi: quyi sinf yuqorini almashtira oladi), I (Interface Segregation — interfeys ajratish: kichik, maxsus interfeyslar), D (Dependency Inversion — bog'liqlik teskariligi: abstraksiyaga bog'lan, aniqga emas). Bu tamoyillar o'zgartirishni oson qiladi (yaxshi dizaynning maqsadi — o'zgarishga tayyorlik). SOLID — moslashuvchan dizayn qoidalari.
Real vaziyat. Bir loyihada Order sinfi hammasini qilar edi: hisoblash, saqlash, email yuborish, PDF chiqarish. Email tizimi o'zgarganda — Order o'zgardi (nega buyurtma email uchun o'zgaradi?). Sinf bo'lindi: Order (mantiq), OrderRepository (saqlash), EmailService (email) — har biri bir mas'uliyat (SRP). Endi email o'zgarsa — faqat EmailService. Yangi to'lov turi — yangi sinf (OCP, Order tegilmaydi). SOLID — o'zgartirish xavfsizligi.
Bu darsda SOLID tamoyillarini o'rganamiz.
Bu darsda:
- SOLID nima
- S — Single Responsibility (bir mas'uliyat)
- O — Open/Closed (ochiq/yopiq)
- L — Liskov Substitution (almashinuv)
- I — Interface Segregation (interfeys ajratish)
- D — Dependency Inversion (bog'liqlik teskarisi)
- SOLID birgalikda
- Amaliy: SOLID qo'llash
ℹ Misollarda SOLID sof Python (sinflar,
Protocol,ABC) bilan ko'rsatiladi — deterministik.
2. Nazariya — chuqur tushuntirish
2.1. SOLID nima
Besh dizayn tamoyili:
S — Single Responsibility (bir mas'uliyat)
O — Open/Closed (ochiq/yopiq)
L — Liskov Substitution (almashinuv)
I — Interface Segregation (interfeys ajratish)
D — Dependency Inversion (bog'liqlik teskarisi)SOLID — obyektga yo'naltirilgan dizaynning besh tamoyili (Robert Martin): sinflarni moslashuvchan (o'zgartirish oson), kengaytiriladigan (yangi imkoniyat qo'shish oson), sinaladigan qiladi. Har tamoyil — bir muammoga qarshi (shishgan sinf, mo'rt kengaytirish, noto'g'ri meros). Maqsad: o'zgartirishga tayyorlik (kod o'zgaradi — yaxshi dizayn o'zgarishni yengillashtiradi). SOLID — tamoyil (qat'iy qonun emas — kontekstda qo'llanadi). SOLID — yaxshi OOP dizayni.
2.2. S — Single Responsibility (bir mas'uliyat)
Sinf bir sababga o'zgaradi:
# yomon: Order hammasini qiladi
class Order:
def hisobla(self): ...
def saqla(self): ... # baza
def email_yubor(self): ... # email
# yaxshi: har biri bir mas'uliyat
class Order: def hisobla(self): ...
class OrderRepository: def saqla(self): ...
class EmailService: def yubor(self): ... SRP (Single Responsibility Principle) — sinf bir mas'uliyatga (bir o'zgarish sababiga) ega bo'lishi kerak: Order faqat buyurtma mantigi (hisoblash), saqlash — OrderRepository, email — EmailService. Sabab: sinf ko'p ish qilsa — bir o'zgarish (email formati) boshqasini (buyurtma) xavf ostiga qo'yadi; ajratilgan — har o'zgarish alohida. Belgi: sinf tavsifi "va" bilan (hisoblaydi va saqlaydi) — bo'lish kerak. SRP — 27.1 (kichik funksiya) ning sinf darajasi. Bir sinf — bir sabab.
2.3. O — Open/Closed (ochiq/yopiq)
Kengaytirishga ochiq, o'zgartirishga yopiq:
# yomon: yangi shakl → if qo'shish (o'zgartirish)
def yuza(shakl):
if shakl.turi == "doira": ...
elif shakl.turi == "kvadrat": ... # yangi → shu yerni o'zgartir
# yaxshi: yangi shakl → yangi sinf (o'zgartirishsiz)
class Shakl: def yuza(self): ...
class Doira(Shakl): def yuza(self): ... OCP (Open/Closed Principle) — kod kengaytirishga ochiq (yangi xulq qo'shish mumkin), lekin o'zgartirishga yopiq (mavjud kod tegilmaydi): yangi shakl qo'shish — yangi sinf (mavjud if/elif ni o'zgartirmasdan). Sabab: mavjud, sinalgan kodni o'zgartirish — xato xavfi (ishlayotgan narsani buzish); yangi kod qo'shish — xavfsiz. Yechim: abstraksiya (asosiy sinf/interfeys) + polimorfizm (16-qism). OCP — o'zgarishni qo'shimcha bilan (o'zgartirish emas). Ochiq kengaytirishga, yopiq buzishga.
2.4. L — Liskov Substitution (almashinuv)
Quyi sinf yuqorini almashtira oladi:
# quyi sinf yuqori turgan joyda ishlashi kerak
class Qush: def uch(self): ...
class Burgut(Qush): def uch(self): ... # ✅ ucha oladi
class Tuyaqush(Qush): def uch(self): # ⚠️ ucholmaydi — LSP buziladi
raise Error("ucholmaydi") LSP (Liskov Substitution Principle) — quyi sinf (voris) yuqori sinf o'rniga ishlashi kerak (dasturni buzmasdan): Qush kutilgan joyga Burgut (ucha oladi) mos, Tuyaqush (ucholmaydi) — LSP buzadi (kutilgan xulqni bajarmaydi). Sabab: agar voris ota-sinf va'dasini bajarmasa (xato tashlaydi, boshqacha ishlaydi) — polimorfizm ishonchsiz (voris qo'yilsa — buziladi). Belgi: voris metodi NotImplementedError yoki cheklov qo'shadi — meros noto'g'ri. LSP — merosda va'daga sodiqlik. Voris — otani almashtira olishi kerak.
2.5. I — Interface Segregation (interfeys ajratish)
Kichik, maxsus interfeyslar:
# yomon: katta interfeys (hamma majbur)
class Ishchi:
def ishla(self): ...
def ovqatlan(self): ... # robot ovqatlanmaydi!
# yaxshi: ajratilgan
class Ishlaydigan: def ishla(self): ...
class Ovqatlanadigan: def ovqatlan(self): ... ISP (Interface Segregation Principle) — kichik, maxsus interfeyslar (bitta katta emas): mijoz faqat kerak metodlarga bog'lanishi kerak (ishlatmaydiganga emas). Masalan katta Ishchi interfeysi (ishla, ovqatlan) — Robot uchun ovqatlan keraksiz (majbur qiladi). Yechim: kichik interfeyslar (Ishlaydigan, Ovqatlanadigan) — har kim keragini oladi. Sabab: katta interfeys — keraksiz bog'liqlik (o'zgarsa — bog'langanlar ta'sirlanadi). ISP — SRP interfeys darajasida. Kichik interfeys — kam bog'liqlik.
2.6. D — Dependency Inversion (bog'liqlik teskarisi)
Abstraksiyaga bog'lan, aniqga emas:
# yomon: yuqori sinf aniq quyiga bog'liq
class Xabarchi:
def __init__(self): self.email = EmailYuboruvchi() # aniq
# yaxshi: abstraksiyaga (interfeys)
class Xabarchi:
def __init__(self, yuboruvchi: Yuboruvchi): # abstraksiya
self.yuboruvchi = yuboruvchi DIP (Dependency Inversion Principle) — yuqori daraja moduli quyiga aniq bog'lanmasligi kerak; ikkalasi abstraksiyaga bog'lanishi kerak: Xabarchi aniq EmailYuboruvchi ga emas, Yuboruvchi interfeysiga bog'lanadi (email, SMS — almashtiriladi). Sabab: aniqga bog'liqlik — qattiq (email o'zgarsa — Xabarchi o'zgaradi, sinash qiyin); abstraksiya — moslashuvchan (istalgan yuboruvchi beriladi — DI, dependency injection). DIP — bog'liqlik yo'nalishini teskari (aniqga emas, abstraksiyaga). Abstraksiyaga bog'lan.
2.7. SOLID birgalikda
SOLID tamoyillari birga ishlaydi: SRP (bir mas'uliyat) sinflarni bo'ladi, OCP (kengaytirish) va DIP (abstraksiya) yangi imkoniyatni oson qiladi, LSP (almashinuv) polimorfizni ishonchli qiladi, ISP (kichik interfeys) bog'liqlikni kamaytiradi. Umumiy g'oya: o'zgartirishga tayyorlik — sinflar kichik, aniq, abstraksiya orqali bog'langan (o'zgarish bir joyda, kengaytirish qo'shimcha bilan). Lekin SOLID — tamoyil, qonun emas: haddan oshirish (har narsaga interfeys) — murakkablik (KISS — 27.1). Muvozanat: SOLID o'zgarish kutilgan joyda. SOLID — moslashuvchan, lekin ortiqcha emas.
2.8. SOLID — dizaynning maqsadi
SOLID — obyektga yo'naltirilgan dizaynning maqsadini ochadi: kod o'zgaradi (talab o'zgaradi, yangi imkoniyat) — yaxshi dizayn o'zgarishni oson va xavfsiz qiladi. SOLID buni ta'minlaydi: o'zgarish cheklangan (bir sinf — SRP), qo'shimcha bilan (yangi sinf — OCP), almashinuvchan (abstraksiya — DIP). Bu naqshlar (27.3–27.5 — SOLID ni amalga oshiradigan yechimlar), qatlamlar 27.6-bob, Clean Architecture 27.7-bob uchun asos. SOLID toza kod 27.1-bob ustiga quriladi (nomlash, kichik funksiya + sinf dizayni). SOLID — o'zgarishni boshqarish. Yaxshi dizayn — o'zgarishga tayyor dizayn.
3. Tez ma'lumotnoma
# S — Single Responsibility (bir sabab)
class Order: hisobla() # mantiq
class OrderRepo: saqla() # saqlash
class Email: yubor() # email
# O — Open/Closed (yangi = yangi sinf)
class Shakl(ABC): def yuza(self): ...
class Doira(Shakl): ... # yangi, mavjud tegilmaydi
# L — Liskov (voris otani almashtira oladi)
def chiz(sh: Shakl): sh.yuza() # har voris ishlashi kerak
# I — Interface Segregation (kichik interfeys)
class Ishlaydigan(Protocol): def ishla(self): ...
class Ovqatlanadigan(Protocol): def ovqatlan(self): ...
# D — Dependency Inversion (abstraksiyaga)
class X:
def __init__(self, y: Yuboruvchi): # interfeys, aniq emas
self.y = ySOLID xulosasi
S — bir mas'uliyat (bir o'zgarish sababi)
O — kengaytirishga ochiq, o'zgartirishga yopiq
L — voris otani almashtira oladi (va'daga sodiq)
I — kichik, maxsus interfeys (keraksizga bog'lanma)
D — abstraksiyaga bog'lan (aniqga emas — DI)
Maqsad: o'zgarishga tayyorlik (oson, xavfsiz)4. Batafsil misollar
Misollarda SOLID sof Python (sinflar,
ABC,Protocol) bilan ko'rsatiladi.
Misol 1 — SRP: mas'uliyatlarni ajratish
"""SRP: bir sinf bir mas'uliyat (mantiq, saqlash, xabar alohida)."""
class Buyurtma:
"""Faqat buyurtma mantigi (bir mas'uliyat)."""
def __init__(self, mahsulot: str, narx: float, soni: int) -> None:
self.mahsulot = mahsulot
self.narx = narx
self.soni = soni
def jami(self) -> float:
return self.narx * self.soni
class BuyurtmaOmbori:
"""Faqat saqlash (baza mock)."""
def __init__(self) -> None:
self.saqlangan: list = []
def saqla(self, b: Buyurtma) -> None:
self.saqlangan.append(b.mahsulot)
class XabarXizmati:
"""Faqat xabar."""
def yubor(self, b: Buyurtma) -> str:
return f"'{b.mahsulot}' buyurtma qabul qilindi ({b.jami()})"
def main() -> None:
buyurtma = Buyurtma("Python kursi", 100, 2)
print("=== 1. Buyurtma mantigi (Buyurtma) ===")
print(f" jami: {buyurtma.jami()}")
print("\n=== 2. Saqlash (BuyurtmaOmbori) ===")
ombor = BuyurtmaOmbori()
ombor.saqla(buyurtma)
print(f" saqlangan: {ombor.saqlangan}")
print("\n=== 3. Xabar (XabarXizmati) ===")
xabar = XabarXizmati()
print(f" {xabar.yubor(buyurtma)}")
print("\n=== 4. Har biri bir sababga o'zgaradi ===")
print(" Buyurtma → narx mantigi o'zgarsa")
print(" Ombor → baza o'zgarsa")
print(" Xabar → email formati o'zgarsa")
print(" ⭐ SRP — bir sinf, bir mas'uliyat")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Buyurtma mantigi (Buyurtma) ===
jami: 200
=== 2. Saqlash (BuyurtmaOmbori) ===
saqlangan: ['Python kursi']
=== 3. Xabar (XabarXizmati) ===
'Python kursi' buyurtma qabul qilindi (200)
=== 4. Har biri bir sababga o'zgaradi ===
Buyurtma → narx mantigi o'zgarsa
Ombor → baza o'zgarsa
Xabar → email formati o'zgarsa
⭐ SRP — bir sinf, bir mas'uliyatNima ko'rsatdi: 2.2-bo'lim.
Misol 2 — OCP: kengaytirishga ochiq
"""OCP: yangi shakl = yangi sinf (mavjud kod o'zgartirilmaydi)."""
from abc import ABC, abstractmethod
class Shakl(ABC):
@abstractmethod
def yuza(self) -> float: ...
class Doira(Shakl):
def __init__(self, radius: float) -> None:
self.radius = radius
def yuza(self) -> float:
return 3.14 * self.radius ** 2
class Kvadrat(Shakl):
def __init__(self, tomon: float) -> None:
self.tomon = tomon
def yuza(self) -> float:
return self.tomon ** 2
# yangi shakl qo'shish — mavjud kod tegilmaydi
class Uchburchak(Shakl):
def __init__(self, asos: float, balandlik: float) -> None:
self.asos = asos
self.balandlik = balandlik
def yuza(self) -> float:
return 0.5 * self.asos * self.balandlik
def umumiy_yuza(shakllar: list) -> float:
# bu funksiya yangi shakl qo'shilsa ham o'zgarmaydi (OCP)
return sum(sh.yuza() for sh in shakllar)
def main() -> None:
shakllar = [Doira(2), Kvadrat(3), Uchburchak(4, 5)]
print("=== 1. Har shakl yuzasi ===")
for sh in shakllar:
print(f" {type(sh).__name__}: {sh.yuza()}")
print("\n=== 2. Umumiy yuza (o'zgarmas funksiya) ===")
print(f" jami: {umumiy_yuza(shakllar)}")
print("\n=== 3. Yangi shakl qo'shish ===")
print(" Uchburchak qo'shildi — umumiy_yuza tegilmadi")
print(" if/elif yo'q (polimorfizm)")
print("\n=== 4. Ochiq/yopiq ===")
print(" ochiq: yangi sinf qo'shiladi")
print(" yopiq: mavjud kod o'zgartirilmaydi")
print(" ⭐ OCP — kengaytir (o'zgartirma)")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Har shakl yuzasi ===
Doira: 12.56
Kvadrat: 9
Uchburchak: 10.0
=== 2. Umumiy yuza (o'zgarmas funksiya) ===
jami: 31.560000000000002
=== 3. Yangi shakl qo'shish ===
Uchburchak qo'shildi — umumiy_yuza tegilmadi
if/elif yo'q (polimorfizm)
=== 4. Ochiq/yopiq ===
ochiq: yangi sinf qo'shiladi
yopiq: mavjud kod o'zgartirilmaydi
⭐ OCP — kengaytir (o'zgartirma)Nima ko'rsatdi: 2.3-bo'lim.
Misol 3 — LSP: almashinuvchan vorislar
"""LSP: har voris ota o'rnida ishlashi kerak (va'daga sodiq)."""
from abc import ABC, abstractmethod
class Toluv(ABC):
@abstractmethod
def tola(self, summa: float) -> str: ...
class KartaToluv(Toluv):
def tola(self, summa: float) -> str:
return f"Karta: {summa} to'landi"
class NaqdToluv(Toluv):
def tola(self, summa: float) -> str:
return f"Naqd: {summa} to'landi"
class UmsToluv(Toluv):
def tola(self, summa: float) -> str:
return f"UMS: {summa} to'landi"
def toluvni_amalga_oshir(toluv: Toluv, summa: float) -> str:
# har voris bu yerda ishlashi kerak (LSP)
return toluv.tola(summa)
def main() -> None:
toluvlar = [KartaToluv(), NaqdToluv(), UmsToluv()]
print("=== 1. Har to'lov turi ishlaydi ===")
for t in toluvlar:
print(f" {toluvni_amalga_oshir(t, 100)}")
print("\n=== 2. Almashinuvchanlik ===")
print(" har voris Toluv o'rnida ishlaydi")
print(" toluvni_amalga_oshir — turni bilmaydi")
print("\n=== 3. LSP sharti ===")
print(" voris ota va'dasini bajaradi (tola)")
print(" xato tashlamaydi, cheklov qo'shmaydi")
print("\n=== 4. Sanoq ===")
print(f" to'lov turlari: {[type(t).__name__ for t in toluvlar]}")
print(" ⭐ LSP — voris otani almashtira oladi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Har to'lov turi ishlaydi ===
Karta: 100 to'landi
Naqd: 100 to'landi
UMS: 100 to'landi
=== 2. Almashinuvchanlik ===
har voris Toluv o'rnida ishlaydi
toluvni_amalga_oshir — turni bilmaydi
=== 3. LSP sharti ===
voris ota va'dasini bajaradi (tola)
xato tashlamaydi, cheklov qo'shmaydi
=== 4. Sanoq ===
to'lov turlari: ['KartaToluv', 'NaqdToluv', 'UmsToluv']
⭐ LSP — voris otani almashtira oladiNima ko'rsatdi: 2.4-bo'lim.
Misol 4 — DIP: abstraksiyaga bog'lanish
"""DIP: yuqori sinf abstraksiyaga bog'lanadi (aniq emas — almashtiriladi)."""
from abc import ABC, abstractmethod
class Yuboruvchi(ABC):
"""Abstraksiya (interfeys)."""
@abstractmethod
def yubor(self, xabar: str) -> str: ...
class EmailYuboruvchi(Yuboruvchi):
def yubor(self, xabar: str) -> str:
return f"[EMAIL] {xabar}"
class SmsYuboruvchi(Yuboruvchi):
def yubor(self, xabar: str) -> str:
return f"[SMS] {xabar}"
class Xabarchi:
"""Yuqori sinf — abstraksiyaga bog'liq (aniq yuboruvchiga emas)."""
def __init__(self, yuboruvchi: Yuboruvchi) -> None:
self.yuboruvchi = yuboruvchi # DI (tashqaridan beriladi)
def ogohlantir(self, kim: str) -> str:
return self.yuboruvchi.yubor(f"Salom {kim}!")
def main() -> None:
print("=== 1. Email bilan ===")
x1 = Xabarchi(EmailYuboruvchi())
print(f" {x1.ogohlantir('Ali')}")
print("\n=== 2. SMS bilan (almashtirildi) ===")
x2 = Xabarchi(SmsYuboruvchi())
print(f" {x2.ogohlantir('Ali')}")
print("\n=== 3. Xabarchi o'zgarmadi ===")
print(" bir xil Xabarchi, turli yuboruvchi")
print(" aniq turga bog'liq emas (abstraksiyaga)")
print("\n=== 4. Sinash oson (mock beriladi) ===")
class MockYuboruvchi(Yuboruvchi):
def yubor(self, xabar: str) -> str:
return "[MOCK]"
print(f" test: {Xabarchi(MockYuboruvchi()).ogohlantir('X')}")
print(" ⭐ DIP — abstraksiyaga bog'lan (moslashuvchan)")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Email bilan ===
[EMAIL] Salom Ali!
=== 2. SMS bilan (almashtirildi) ===
[SMS] Salom Ali!
=== 3. Xabarchi o'zgarmadi ===
bir xil Xabarchi, turli yuboruvchi
aniq turga bog'liq emas (abstraksiyaga)
=== 4. Sinash oson (mock beriladi) ===
test: [MOCK]
⭐ DIP — abstraksiyaga bog'lan (moslashuvchan)Nima ko'rsatdi: 2.6-bo'lim.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "SOLID — qat'iy qonun" | Tamoyil (kontekstda) |
| "Sinf ko'p ish qilsa bo'ladi" | SRP (bir mas'uliyat) |
| "Yangi = if qo'shish" | OCP (yangi sinf) |
| "Meros erkin" | LSP (va'daga sodiq) |
| "Katta interfeys qulay" | ISP (kichik) |
| "Aniq turga bog'lan" | DIP (abstraksiya) |
| "SOLID = ko'p sinf" | O'zgarishga tayyorlik |
| "Har narsaga interfeys" | Muvozanat (KISS) |
6. Keng tarqalgan xatolar va yechimlari
1. Xudo sinfi (hammasini qiladi)
class Order: hisobla(); saqla(); email() # ⚠️ SRP buziladi
# ajrat: Order, Repository, Email # ✅2. if/elif tur bo'yicha
if shakl.turi == "doira": ... # ⚠️ OCP buziladi
class Doira(Shakl): def yuza(self) # ✅ polimorfizm3. Voris va'dani buzadi
class Tuyaqush(Qush): def uch(self): raise # ⚠️ LSP buziladi
# to'g'ri ierarxiya (Ucholadigan alohida) # ✅4. Semiz interfeys
class Ishchi: ishla(); ovqatlan() # robot? # ⚠️ ISP buziladi
# Ishlaydigan, Ovqatlanadigan (ajrat) # ✅5. Aniqga bog'liqlik
self.db = PostgresDB() # aniq # ⚠️ DIP buziladi
def __init__(self, db: Database): ... # ✅ abstraksiya6. Haddan SOLID (murakkablik)
# har oddiy narsaga interfeys, factory # ⚠️ ortiqcha
# SOLID o'zgarish kutilgan joyda # ✅ muvozanat7. DI qo'lda (har joyda yaratish)
Xabarchi(EmailYuboruvchi()) # har joyda # ⚠️
# DI konteyner yoki bir joyda sozlash # ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 27.1-dars (o'tilgan): Toza kod — SOLID asosi
- 27.3–27.5-dars: Naqshlar — SOLID ni amalga oshiradi
- 27.6-dars: Qatlamlar — DIP bilan
- 16-qism (o'tilgan): OOP — meros, polimorfizm
- 20-qism (o'tilgan): FastAPI — DI (Depends)
8. Eng yaxshi amaliyotlar
SRP — sinf bir sababga o'zgarsin.
OCP — yangi xulq yangi sinf bilan.
LSP — voris otani to'liq almashtirsin.
ISP — kichik, maxsus interfeys.
DIP — abstraksiyaga bog'lan (DI).
Muvozanat — SOLID o'zgarish kutilganda.
KISS bilan (haddan SOLID emas).
Protocol/ABC— abstraksiya uchun.
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # SOLID nima?
2. # S nima?
3. # SRP: sinf necha sababga o'zgaradi?
4. # O nima?
5. # OCP: yangi xulq qanday?
6. # L nima?
7. # LSP sharti?
8. # I nima?
9. # ISP: interfeys qanday?
10. # D nima?
11. # DIP: nimaga bog'lanadi?
12. # DI nima?Javoblar
- Besh OOP dizayn tamoyili
- Single Responsibility
- Bir sababga
- Open/Closed
- Yangi sinf (o'zgartirishsiz)
- Liskov Substitution
- Voris otani almashtira oladi
- Interface Segregation
- Kichik, maxsus
- Dependency Inversion
- Abstraksiyaga (aniq emas)
- Dependency Injection (tashqaridan berish)
Vazifa 2: Xatolarni tuzating
1. class Order: hisobla; saqla; email # SRP
2. if shakl.turi == "doira" # OCP
3. class Tuyaqush: uch → raise # LSP
4. class Ishchi: ishla; ovqatlan # ISP
5. self.db = PostgresDB() # DIPJavoblar
1. Order, Repository, Email (ajrat)
2. class Doira(Shakl): yuza (polimorfizm)
3. Ucholadigan alohida (to'g'ri ierarxiya)
4. Ishlaydigan, Ovqatlanadigan (ajrat)
5. def __init__(self, db: Database)Vazifa 3: SRP
Ajrating:
- Xudo sinfi
- Mas'uliyatlar
- Sinflar
- Bir sabab
Vazifa 4: OCP
Kengaytiring:
- Abstraksiya
- Voris
- Polimorfizm
- O'zgartirishsiz
Vazifa 5: LSP
Tekshiring:
- Voris
- Va'da
- Almashinuv
- Buzilish
Vazifa 6: DIP
Bog'lang:
- Abstraksiya
- Voris
- DI
- Sinash
Vazifa 7: O'ylash
SOLID tamoyillarining umumiy maqsadi — o'zgarishga tayyorlik (kod o'zgaradi — yaxshi dizayn buni oson qiladi). Lekin SOLID ni haddan qo'llash (har narsaga interfeys, factory, abstraksiya) — murakkablik (KISS buziladi). Nima uchun "o'zgarish kutilgan joy" ni oldindan bilish qiyin (va shuning uchun SOLID ni qachon qo'llash — mahorat), va nega "ortiqcha dizayn" (haddan SOLID) "kam dizayn" (SOLID yo'q) kabi xatarli?
Javob
Qisqa javob: "O'zgarish kutilgan joy"ni oldindan bilish qiyin, chunki: kelajakni aniq bilmaymiz (qaysi qism o'zgaradi — talab, texnologiya?). SOLID o'zgarishni oson qiladi, lekin har joyga SOLID — narx (murakkablik, ko'p sinf, abstraksiya). Muvozanat: SOLID ni o'zgarish ehtimoli yuqori joyga (to'lov turlari ko'payadi — OCP; ma'lumot manbai o'zgaradi — DIP), oddiy/barqaror joyga — sodda (KISS). Buni bilish tajriba (domenni tushunish — nima o'zgaradi) va mahorat (qachon abstraksiya, qachon sodda). "Ortiqcha dizayn" (haddan SOLID) xatarli, chunki: murakkablik (ko'p sinf, interfeys — o'qish, tushunish qiyin), erta abstraksiya (noto'g'ri — kelajakni taxmin qildik, xato chiqdi — abstraksiya mos kelmaydi, qayta yozish), YAGNI buzilishi (You Aren't Gonna Need It — kerak bo'lmas narsani qurdik). "Kam dizayn" (SOLID yo'q) ham xatarli: qattiq (o'zgartirish qiyin), mo'rt (bir o'zgarish boshqasini buzadi), shishgan (xudo sinflar). Ikkalasi — muvozanatsizlik (biri kam, biri ko'p). Yechim: "amaliy SOLID" — o'zgarish ko'ringanda refactoring (avval sodda, o'zgarish talab qilganda SOLID qo'sh) — "uch marta qoidasi" (bir marta yoz, ikki marta chida, uchinchida abstraksiya). Muhandis saboqi: dizayn — muvozanat (o'zgarish moslashuvi vs oddiylik); tajriba qachon qaysini tanlashni o'rgatadi.
1. Nega kelajak noaniq
Qaysi qism o'zgaradi — bilmaymiz (talab, texnologiya). SOLID har joyga — narx (murakkablik).
2. Muvozanat (qayerga SOLID)
| Joy | Yondashuv |
|---|---|
| O'zgarish ehtimoli yuqori | SOLID (moslashuvchan) |
| Barqaror, oddiy | Sodda (KISS) |
3. Ortiqcha dizayn xatari
- Murakkablik (ko'p sinf — o'qish qiyin)
- Erta abstraksiya (noto'g'ri taxmin — qayta yozish)
- YAGNI (kerak bo'lmas narsa)
4. Kam dizayn xatari
- Qattiq (o'zgartirish qiyin)
- Mo'rt (bir o'zgarish boshqasini buzadi)
- Shishgan (xudo sinflar)
5. Amaliy yechim
"Uch marta qoidasi": avval sodda, o'zgarish talab qilganda SOLID qo'sh (refactoring). Erta emas, kech emas.
6. Xulosa
- Kelajak noaniq — o'zgarish joyini taxmin qiyin
- Muvozanat: SOLID o'zgarishga, sodda barqarorga
- Ortiqcha (murakkab) va kam (qattiq) — ikki xato
- Amaliy SOLID: o'zgarish ko'ringanda qo'sh (mahorat)
Nimani mustahkamlaydi: 2.7, 2.8-bo'limlar.
Xulosa
Bu darsda SOLID tamoyillarini o'rgandik.
Eng muhim uch fikr:
SOLID va SRP, OCP. SOLID — obyektga yo'naltirilgan dizaynning besh tamoyili (sinflarni moslashuvchan, kengaytiriladigan, sinaladigan qiladi — maqsad: o'zgarishga tayyorlik). S — SRP (Single Responsibility): sinf bir mas'uliyatga (bir o'zgarish sababiga) ega —
Order(mantiq),OrderRepository(saqlash),EmailService(email) alohida (belgi: tavsif "va" bilan — bo'lish). O — OCP (Open/Closed): kod kengaytirishga ochiq, o'zgartirishga yopiq — yangi shakl = yangi sinf (mavjudif/elifni o'zgartirmasdan), abstraksiya + polimorfizm bilan.LSP, ISP, DIP. L — LSP (Liskov Substitution): quyi sinf (voris) yuqori o'rnida ishlashi kerak (dasturni buzmasdan) —
Tuyaqush(ucholmaydi)Qusho'rniga mos emas (LSP buzadi — voris ota va'dasini bajarmaydi). I — ISP (Interface Segregation): kichik, maxsus interfeyslar — mijoz faqat kerak metodlarga bog'lansin (Robotuchunovqatlankeraksiz —Ishlaydigan/Ovqatlanadiganajrat). D — DIP (Dependency Inversion): yuqori daraja quyiga aniq emas, ikkalasi abstraksiyaga bog'lansin —XabarchianiqEmailYuboruvchiga emas,Yuboruvchiinterfeysiga (DI — dependency injection, tashqaridan berish; email/SMS almashtiriladi, sinash oson).SOLID birgalikda va muvozanat. SOLID tamoyillari birga: SRP bo'ladi, OCP+DIP kengaytiradi, LSP polimorfizni ishonchli qiladi, ISP bog'liqlikni kamaytiradi — umumiy g'oya o'zgarishni oson va xavfsiz qilish. Lekin SOLID — tamoyil, qonun emas: haddan qo'llash (har narsaga interfeys) — murakkablik (KISS buziladi); "ortiqcha dizayn" (erta abstraksiya, YAGNI) va "kam dizayn" (qattiq, mo'rt, xudo sinf) — ikki xato. Amaliy yechim: "uch marta qoidasi" (o'zgarish talab qilganda SOLID qo'sh — refactoring, erta emas). SOLID — toza kod 27.1-bob ustiga quriladi va naqshlar (27.3–27.5), qatlamlar 27.6-bob, Clean Architecture 27.7-bob uchun asos. Yaxshi dizayn — o'zgarishga tayyor dizayn (muvozanat bilan).
Keyingi darsda dizayn naqshlari: yaratuvchi (creational) ni o'rganamiz: obyekt yaratishning takrorlanuvchi yechimlari (Factory, Singleton, Builder, Prototype) — SOLID ni amalda qo'llaydigan tayyor andozalar.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!