# 05. Structural: Adapter Pattern — Eski va Yangi Dunyo Ko'prigi

> "Siz yangi uyingizga eng zamonaviy yevro-vilka sotib oldingiz, ammo devordagi rozetka eski sovet standartida. Rozetkani buzib devorni sindirasizmi yoki 1 dollarlik o'tish moslamasi (adapter) qo'yasizmi? Adapter patterni dasturiy ta'minotning aynan o'sha o'tish moslamasidir."

---

## 1. Adapter Pattern Nima va U Qaysi Muammoni Hal Qiladi?

**Adapter (Wrapper)** — bu ikki xil mos kelmaydigan interfeysga ega bo'lgan sinflarni bir-biri bilan hamkorlikda ishlashiga imkon beruvchi tuzilmaviy pattern.

```mermaid
flowchart LR
    Client["Bizning Swift 6 Ilovamiz\n(Kutadi: async/await Protocol)"] --> Adapter["LocationServiceAdapter\n(Moslashtiruvchi Ko'prik)"]
    Adapter --> LegacySDK["Eski 3rd Party SDK\n(Obj-C / Callback Closures / Delegates)"]

    style Client fill:#131720,stroke:#bef264,stroke-width:2px
    style Adapter fill:#181d26,stroke:#7da2ce,stroke-width:2px
    style LegacySDK fill:#251014,stroke:#f87171,stroke-width:1px
```

### Haqiqiy iOS Loyihalardagi Muammo:
1. Kompaniyangiz eski Objective-C da yozilgan yoki begona kompaniyaning xunuk SDK'sini (masalan, eski Xaritalar yoki To'lov SDK'si) ishlatishga majbur.
2. Bu SDK eski completion-handler callbacklar yoki murakkab xunuk metodlar bilan ishlaydi.
3. Agar siz butun ViewModel va Use Case laringiz ichiga o'sha xunuk SDK sinflarini to'g'ridan-to'g'ri chaqirib yozsangiz, ertaga o'sha SDK'ni boshqasiga (masalan, Google Maps'dan Apple MapKit'ga) almashtirishga to'g'ri kelsa — butun loyihaning 50 ta faylini qayta yozishingizga to'g'ri keladi!

---

## 2. Class Adapter vs Object Adapter: Nega Swift'da Composition G'alaba Qozonadi?

Nazariyada ikkita turli Adapter mavjud:
1. **Class Adapter:** Vorislik (Inheritance) orqali eski sinfdan meros oladi va yangi protokolni tasdiqlaydi. Swift'da ko'p karra vorislik (Multiple Inheritance) taqiqlangani sababli bu usul deyarli ishlatilmaydi.
2. **Object Adapter:** Kompozitsiya (Composition) orqali eski SDK'ni o'zining ichida xususiy (private) obyekt sifatida saqlaydi va unga so'rovlarni uzatadi. Bu eng xavfsiz va moslashuvchan yo'ldir.

---

## 3. Real-World Swift 6 Kodi: Callback SDK ni async/await ga Moslash

Keling, eski 3rd party GPS SDK'sini zamonaviy Swift 6 talablariga moslashtiramiz.

### 1. Eski Tashqi SDK (Biz uning kodini o'zgartira olmaymiz):
```swift
// Begona kompaniya kutubxonasi (Legacy SDK)
public final class LegacyTrackerSDK {
    public func fetchCoordinates(completion: @escaping (Double, Double, Error?) -> Void) {
        DispatchQueue.global().asyncAfter(deadline: .now() + 1.0) {
            // Sun'iy koordinata qaytarish
            completion(41.311081, 69.240562, nil)
        }
    }
}
```

### 2. Bizning Loyihamiz Qabul Qiladigan Zamonaviy Kontrakt:
```swift
public struct UserLocation: Sendable {
    public let latitude: Double
    public let longitude: Double
}

public protocol LocationService: Sendable {
    func getCurrentLocation() async throws -> UserLocation
}
```

### 3. Object Adapter:
```swift
public enum LocationError: Error {
    case locationUnavailable
}

public final class LegacyLocationAdapter: LocationService {
    private let legacySDK: LegacyTrackerSDK
    
    public init(legacySDK: LegacyTrackerSDK = LegacyTrackerSDK()) {
        self.legacySDK = legacySDK
    }
    
    public func getCurrentLocation() async throws -> UserLocation {
        // Swift Concurrency ning CheckedContinuation imkoniyati
        // eski callback'ni zamonaviy async/await ga o'girishda eng yaxshi adapterdir!
        return try await withCheckedThrowingContinuation { continuation in
            legacySDK.fetchCoordinates { lat, lng, error in
                if let error = error {
                    continuation.resume(throwing: error)
                } else {
                    let location = UserLocation(latitude: lat, longitude: lng)
                    continuation.resume(returning: location)
                }
            }
        }
    }
}
```

### 4. ViewModel'da Ishlatilishi:
```swift
@MainActor
public final class MapViewModel {
    private let locationService: any LocationService
    
    public init(locationService: any LocationService) {
        self.locationService = locationService
    }
    
    public func updatePosition() async {
        do {
            let loc = try await locationService.getCurrentLocation()
            print("Foydalanuvchi manzili: \(loc.latitude), \(loc.longitude)")
        } catch {
            print("Xatolik: \(error)")
        }
    }
}
```

---

## 4. Katta Yutuq: SDK ni 1 Soniyada Almashtirish

Tasavvur qiling, 6 oydan keyin kompaniya rahbariyati: *"LegacyTrackerSDK juda qimmat ekan, keling Apple'ning CoreLocation tizimiga o'tamiz"* dedi.

Siz ViewModel yoki ekranlarga **birorta ham o'zgartirish kiritmaysiz**! Siz shunchaki yangi `CoreLocationAdapter` yozasiz va Dependency Injection orqali uzatasiz:

```swift
public final class AppleCoreLocationAdapter: LocationService {
    public func getCurrentLocation() async throws -> UserLocation {
        // CoreLocation async API
        return UserLocation(latitude: 41.31, longitude: 69.24)
    }
}
```

Bu toza arxitekturaning va Adapter patternining chinakam qudratidir!

---

## 5. Interaktiv Savol-Javob (Self-Check Quiz)

<details>
<summary><b>1-Savol: Swift'da 'withCheckedContinuation' va 'withCheckedThrowingContinuation' funksiyalari qanday qilib til darajasidagi Adapter hisoblanadi?</b> (Yechimni ko'rish uchun bosing)</summary>

**Tahlil va Yechim:**
Ushbu funksiyalar eski oqim (Completion-handler / Delegate) interfeysini qabul qilib, uni Swift Concurrency (async/await) ga moslashtirib beruvchi standart Apple adapteri vazifasini bajaradi. Ular eski asinxron kodni to'xtatib turadi (`await`) va natija kelganda davom ettiradi (`resume`).
</details>

<details>
<summary><b>2-Savol: Adapter va Facade patternlarining asosiy farqi nimada?</b> (Yechimni ko'rish uchun bosing)</summary>

**Tahlil va Yechim:**
* **Adapter** mavjud interfeysni boshqa bir **aniq kutilayotgan interfeysga moslashtirish** (Convert/Translate qilish) uchun ishlatiladi.
* **Facade** esa interfeysni moslashtirmaydi, balki ko'plab murakkab tizimlarning ustiga **yangidan bitta sodda boshqaruv oynasi** qurib beradi (Simplification).
</details>

---

## 6. Amaliy Topshiriq (Senior Challenge)

Ilovangizda eski NotificationCenter orqali xabar uzatuvchi tizim mavjud:
* Ushbu eski xabarlashuvni `AsyncStream<String>` orqali zamonaviy Swift 6 oqimiga aylantirib beruvchi `NotificationCenterAdapter` sinfini yarating!
