# 06. Structural: Decorator va Facade Pattern

> "Agar siz har safar yangi xususiyat qo'shish uchun sinfdan meros (Inheritance) olaversangiz, 1 oydan keyin `LoggedInEncryptedCachingNetworkClient` degan dahshatli sinflar iyerarxiyasiga ega bo'lasiz. Decorator va Facade kodni o'zgartirmasdan uni boyitish va soddalashtirish san'atidir."

---

## 1. Decorator Pattern: Vorislikka Qarshi Oqilona Yechim

**Decorator (Bezakchi)** — bu mavjud obyektning tuzilishiga va uning ota sinfiga tegmasdan, unga dinamik ravishda yangi xatti-harakat va mas'uliyatlarni qo'shish imkonini beruvchi pattern.

### Vorislik (Inheritance) Nimasi Bilan Yomon?
Agar sizda `BasicNetworkClient` bo'lsa va unga:
* Kesh kerak bo'lsa -> `CachingNetworkClient`
* Log yozish kerak bo'lsa -> `LoggingNetworkClient`
* Ikkalasi ham kerak bo'lsa -> `CachingLoggingNetworkClient`
* Token qo'shish kerak bo'lsa -> `AuthenticatedCachingLoggingNetworkClient`!
Bu sinflar portlashi (Class Explosion) deb ataladi.

```mermaid
flowchart LR
    Request["So'rov Jo'natildi"] --> LoggingDec["LoggingDecorator\n(Console'ga yozadi)"]
    LoggingDec --> CachingDec["CachingDecorator\n(Keshni tekshiradi)"]
    CachingDec --> AuthDec["AuthDecorator\n(Bearer tokenni ulaydi)"]
    AuthDec --> CoreClient["CoreURLSessionClient\n(Haqiqiy tarmoqqa chiqadi)"]

    style CoreClient fill:#131720,stroke:#bef264,stroke-width:2px
    style AuthDec fill:#181d26,stroke:#7da2ce,stroke-width:1px
    style CachingDec fill:#181d26,stroke:#7da2ce,stroke-width:1px
    style LoggingDec fill:#181d26,stroke:#7da2ce,stroke-width:1px
```

---

## 2. Real Swift 6 Kodi: Tarmoq Klientini Decorator Bilan Bezatish

### 1. Asosiy Protokol va Baza Klient:
```swift
import Foundation

public protocol HTTPClient: Sendable {
    func execute(request: URLRequest) async throws -> (Data, HTTPURLResponse)
}

public final class URLSessionHTTPClient: HTTPClient {
    private let session: URLSession
    
    public init(session: URLSession = .shared) {
        self.session = session
    }
    
    public func execute(request: URLRequest) async throws -> (Data, HTTPURLResponse) {
        let (data, response) = try await session.data(for: request)
        guard let httpResponse = response as? HTTPURLResponse else {
            throw URLError(.badServerResponse)
        }
        return (data, httpResponse)
    }
}
```

### 2. Logging Decorator (Baza klient kodiga tegilmaydi!):
```swift
public final class LoggingHTTPClientDecorator: HTTPClient {
    private let decoratee: any HTTPClient
    
    public init(decoratee: any HTTPClient) {
        self.decoratee = decoratee
    }
    
    public func execute(request: URLRequest) async throws -> (Data, HTTPURLResponse) {
        let startTime = CFAbsoluteTimeGetCurrent()
        print("🚀 [HTTP Request] \(request.httpMethod ?? "GET") -> \(request.url?.absoluteString ?? "")")
        
        do {
            let (data, response) = try await decoratee.execute(request: request)
            let duration = (CFAbsoluteTimeGetCurrent() - startTime) * 1000
            print("✅ [HTTP Response] Status: \(response.statusCode) (\(String(format: "%.1f", duration)) ms), Hajm: \(data.count) bayt")
            return (data, response)
        } catch {
            print("❌ [HTTP Error] \(error.localizedDescription)")
            throw error
        }
    }
}
```

### 3. Caching Decorator:
```swift
public final class CachingHTTPClientDecorator: HTTPClient {
    private let decoratee: any HTTPClient
    private let cache = NSCache<NSURL, NSData>()
    
    public init(decoratee: any HTTPClient) {
        self.decoratee = decoratee
    }
    
    public func execute(request: URLRequest) async throws -> (Data, HTTPURLResponse) {
        guard let url = request.url as? NSURL, request.httpMethod == "GET" else {
            return try await decoratee.execute(request: request)
        }
        
        // Keshni tekshirish
        if let cachedData = cache.object(forKey: url) {
            print("⚡ [Cache Hit] Keshdan olindi: \(url.absoluteString ?? "")")
            let mockResponse = HTTPURLResponse(url: url as URL, statusCode: 200, httpVersion: nil, headerFields: nil)!
            return (cachedData as Data, mockResponse)
        }
        
        // Asl chaqiruv
        let (data, response) = try await decoratee.execute(request: request)
        if response.statusCode == 200 {
            cache.setObject(data as NSData, forKey: url)
        }
        return (data, response)
    }
}
```

### Ishlatilishi (Matryoshka qo'g'irchog'i kabi yig'iladi):
```swift
// Bitta oddiy URLSession klientini Logging va Caching bilan bezatamiz:
let baseClient = URLSessionHTTPClient()
let clientWithCache = CachingHTTPClientDecorator(decoratee: baseClient)
let fullClient = LoggingHTTPClientDecorator(decoratee: clientWithCache)

// fullClient chaqirilganda avval Log yoziladi, keyin kesh tekshiriladi, agar yo'q bo'lsa tarmoqqa chiqadi!
```

---

## 3. Facade Pattern: Murakkab Tizimlarni 1 Qatorda Boshqarish

**Facade (Bosh Oyna)** — bu o'zida o'nlab murakkab quyi tizimlarni (Subsystems) birlashtirib, tashqi dunyoga **bitta soddalashtirilgan interfeys** taqdim etuvchi pattern.

```mermaid
graph TD
    Client["ViewController / UI Qatlami"] --> Facade["AppStartupFacade.bootstrap()"]

    subgraph Subsystems["Murakkab Ichki Quyi Tizimlar"]
        direction TB
        S1["DatabaseMigrationService.run()"]
        S2["KeychainService.checkBiometrics()"]
        S3["NotificationHelper.requestPermissions()"]
        S4["AnalyticsService.setupTracker()"]
        S5["RemoteConfig.syncFlags()"]
    end

    Facade --> S1
    Facade --> S2
    Facade --> S3
    Facade --> S4
    Facade --> S5

    style Facade fill:#131720,stroke:#bef264,stroke-width:2px
    style Subsystems fill:#181d26,stroke:#7da2ce,stroke-width:1px
```

### Real Swift 6 Kodi:
```swift
public final class AppStartupFacade {
    private let dbMigration = DatabaseMigrationService()
    private let keychain = KeychainManager()
    private let notifications = NotificationManager()
    private let analytics = AnalyticsManager()
    
    public init() {}
    
    public func bootstrap() async {
        print("Ilova ishga tushirilmoqda...")
        await dbMigration.migrateIfNeeded()
        await keychain.validateAccess()
        await notifications.registerForPushNotifications()
        analytics.configure()
        print("Barcha 4 ta tizim tayyor!")
    }
}
```

Endi `AppDelegate` yoki SwiftUI `App` faylida 50 qator kod yozish o'rniga faqat:
```swift
@main
struct MyApp: App {
    private let startupFacade = AppStartupFacade()
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .task {
                    await startupFacade.bootstrap()
                }
        }
    }
}
```

---

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

<details>
<summary><b>1-Savol: SwiftUI'dagi '.padding().background(.red).cornerRadius(10)' zanjiri qaysi design pattern asosida ishlaydi?</b> (Yechimni ko'rish uchun bosing)</summary>

**Tahlil va Yechim:**
Bu 100% **Decorator Pattern**idir! SwiftUI'dagi har bir `ViewModifier` o'zidan oldingi View'ni o'zining ichiga o'rab (wrap qilib), unga yangi ko'rinish yoki xatti-harakat qo'shadi va yangi bezatilgan View qaytaradi.
</details>

<details>
<summary><b>2-Savol: Facade patterni quyi tizimlarga to'g'ridan-to'g'ri murojaat qilishni taqiqlaydimi?</b> (Yechimni ko'rish uchun bosing)</summary>

**Tahlil va Yechim:**
Yo'q, taqiqlamaydi. Facade faqat ko'p uchraydigan 90% holatlar uchun sodda yo'l beradi. Agar dasturchiga juda kam uchraydigan nozik sozlama kerak bo'lsa, u Facade'ni chetlab o'tib, to'g'ridan-to'g'ri ichki quyi tizim bilan ishlash huquqiga ega bo'lib qoladi.
</details>

---

## 5. Amaliy Topshiriq (Senior Challenge)

`UserLogoutFacade` sinfini yarating:
* Foydalanuvchi "Chiqish" (Logout) tugmasini bosganda u ketma-ket:
  1. `KeychainManager.deleteTokens()`
  2. `SQLiteDatabase.clearUserTables()`
  3. `ImageCache.clearMemory()`
  4. `PushNotificationManager.unregisterDeviceToken()`
  bajarilishini nazorat qilsin va muvaffaqiyatli yakunlangach UI ga xabar bersin!
