Published on

Swiftda Design Patterns

Authors

Design Pattern — dasturlashda takroriy muammolarga sinovdan o'tgan yechimlar. Ular 1994 yilda "Gang of Four" kitobida tizimlashtrilgan va bugungi kunda har bir dasturchi bilishi kerak bo'lgan asosiy tushunchalar. iOS dasturlashda ularning aksariyati har kuni ishlatiladi — ba'zan bilmasdan ham (masalan, URLSession.shared — Singleton pattern).

Factory Pattern — ob'ekt yaratish

Factory — ob'ekt yaratish logikasini alohida joyga chiqarish. Chaqiruvchi aniq qaysi tur yaratilishini bilmasligi kerak — factory o'zi qaror qiladi. Bu yangi tur qo'shishni osonlashtiradi — faqat factory ga yangi case qo'shish yetarli.

// ═══════════════════════════════════════
//  FACTORY — turli ob'ektlarni yaratish
//  Chaqiruvchi aniq turni bilishi shart emas
// ═══════════════════════════════════════
protocol Bildirishnoma {
    func yuborish(xabar: String)
}

struct EmailBildirishnoma: Bildirishnoma {
    func yuborish(xabar: String) { print("📧 Email: \(xabar)") }
}

struct SMSBildirishnoma: Bildirishnoma {
    func yuborish(xabar: String) { print("📱 SMS: \(xabar)") }
}

struct PushBildirishnoma: Bildirishnoma {
    func yuborish(xabar: String) { print("🔔 Push: \(xabar)") }
}

// Factory — qaysi turni yaratishni hal qiladi
enum BildirishnomaTuri {
    case email, sms, push
}

struct BildirishnomaFactory {
    static func yarat(turi: BildirishnomaTuri) -> Bildirishnoma {
        switch turi {
        case .email: return EmailBildirishnoma()
        case .sms:   return SMSBildirishnoma()
        case .push:  return PushBildirishnoma()
        }
    }
}

// Ishlatish — chaqiruvchi aniq turni bilmaydi
let bildirishnoma = BildirishnomaFactory.yarat(turi: .push)
bildirishnoma.yuborish(xabar: "Salom!") // 🔔 Push: Salom!

Observer Pattern — kuzatish

Observer — ob'ekt o'zgarganda barcha kuzatuvchilarga avtomatik xabar berish. SwiftUI da @Published + ObservableObject aynan shu pattern. UIKit da NotificationCenter va Combine framework ham Observer pattern ga asoslangan. Asosiy g'oya: ma'lumot o'zgarganda siz hech qayerga qo'ng'iroq qilmaysiz — barcha kuzatuvchilar avtomatik yangilanadi.

// ═══════════════════════════════════════
//  OBSERVER — o'zgarishni kuzatish
//  SwiftUI da @Published aynan shu pattern
// ═══════════════════════════════════════
protocol Kuzatuvchi: AnyObject {
    func yangilandi(yangiQiymat: Int)
}

class HaroratSensor {
    // Kuzatuvchilar ro'yxati — weak (retain cycle oldini olish)
    private var kuzatuvchilar: [Kuzatuvchi] = []

    var harorat: Int = 0 {
        didSet {
            // Barcha kuzatuvchilarga xabar berish
            xabarBerish()
        }
    }

    func qoshish(_ kuzatuvchi: Kuzatuvchi) {
        kuzatuvchilar.append(kuzatuvchi)
    }

    private func xabarBerish() {
        kuzatuvchilar.forEach { $0.yangilandi(yangiQiymat: harorat) }
    }
}

class HaroratKorinishi: Kuzatuvchi {
    let nomi: String
    init(nomi: String) { self.nomi = nomi }

    func yangilandi(yangiQiymat: Int) {
        print("\(nomi): Harorat \(yangiQiymat)°C")
    }
}

// Ishlatish
let sensor = HaroratSensor()
let ekran = HaroratKorinishi(nomi: "Ekran")
let ogohlantirish = HaroratKorinishi(nomi: "Ogohlantirish")

sensor.qoshish(ekran)
sensor.qoshish(ogohlantirish)

sensor.harorat = 30
// Ekran: Harorat 30°C
// Ogohlantirish: Harorat 30°C

Delegate Pattern — vakolatni berish

Delegate — iOS da eng ko'p ishlatiladigan pattern. Ob'ekt ba'zi vazifalarni boshqa ob'ektga topshiradi — protokol orqali. UIKit deyarli hamma joyda delegate ishlatadi: UITableViewDelegate, UITextFieldDelegate, UIScrollViewDelegate. weak reference — retain cycle (xotira leak) oldini olish uchun shart.

// ═══════════════════════════════════════
//  DELEGATE — vazifani boshqaga topshirish
//  iOS da eng ko'p ishlatiladigan pattern
// ═══════════════════════════════════════
protocol FormaDelegati: AnyObject {
    func formaYuborildi(ism: String, email: String)
    func formaBekorQilindi()
}

class FormaKorinishi {
    // weak — retain cycle oldini olish
    weak var delegate: FormaDelegati?

    func yuborishBosildi() {
        delegate?.formaYuborildi(ism: "Ali", email: "ali@mail.com")
    }

    func bekorBosildi() {
        delegate?.formaBekorQilindi()
    }
}

// Delegate ni qo'llash
class BoshSahifaController: FormaDelegati {
    let forma = FormaKorinishi()

    init() {
        forma.delegate = self  // Men delegate man
    }

    func formaYuborildi(ism: String, email: String) {
        print("Qabul qilindi: \(ism), \(email)")
    }

    func formaBekorQilindi() {
        print("Bekor qilindi")
    }
}

Strategy Pattern — algoritmni almashtirish

Strategy — algoritmni runtime da almashtirish imkonini beradi. Turli xulq-atvorlar bitta protokol orqali beriladi. Yangi strategiya qo'shish uchun mavjud kodni o'zgartirish shart emas — faqat yangi struct yaratish yetarli. Bu Open/Closed Principle (kengaytirish uchun ochiq, o'zgartirish uchun yopiq).

// ═══════════════════════════════════════
//  STRATEGY — turli xulq-atvorlarni almashtirish
// ═══════════════════════════════════════
protocol TartiblashStrategiyasi {
    func tartibla(_ massiv: [Int]) -> [Int]
}

struct OsishBoyicha: TartiblashStrategiyasi {
    func tartibla(_ massiv: [Int]) -> [Int] {
        massiv.sorted()  // 1, 2, 3
    }
}

struct KamayishBoyicha: TartiblashStrategiyasi {
    func tartibla(_ massiv: [Int]) -> [Int] {
        massiv.sorted(by: >)  // 3, 2, 1
    }
}

struct TasodifiyTartib: TartiblashStrategiyasi {
    func tartibla(_ massiv: [Int]) -> [Int] {
        massiv.shuffled()
    }
}

// Strategiyani runtime da almashtirish
class Royxat {
    var strategiya: TartiblashStrategiyasi

    init(strategiya: TartiblashStrategiyasi = OsishBoyicha()) {
        self.strategiya = strategiya
    }

    func tartiblash(_ sonlar: [Int]) -> [Int] {
        strategiya.tartibla(sonlar)
    }
}

let royxat = Royxat()
print(royxat.tartiblash([3, 1, 2]))  // [1, 2, 3]

royxat.strategiya = KamayishBoyicha()
print(royxat.tartiblash([3, 1, 2]))  // [3, 2, 1]

Patternlar jadvali

PatternMuammoYechimiOS misol
FactoryOb'ekt yaratish murakkabFactory class qaror qiladiURLSessionConfiguration
ObserverO'zgarishni kuzatishKuzatuvchilar ro'yxati@Published, NotificationCenter
DelegateVazifani boshqaga berishProtokol orqaliUITableViewDelegate
StrategyAlgoritmni almashtirishProtokol + turli implementatsiyalarSorting, Validation
SingletonBitta nusxashared staticURLSession.shared

🎯 Topshiriq

TolovStrategyProtocol yarating. 3 ta strategiya: KartaTolov, NaqdTolov, OnlineTolov. Har biri tolov(summa:) metodini turlicha amalga oshirsin. Kassa classida strategiyani runtime da almashtirib, turli to'lov usullarini sinab ko'ring.

Buy mea coffee