# 07. Structural: Composite va Proxy Pattern

> "Daraxtsimon tuzilmalar (papka ichida papka, view ichida view) bilan ishlaganda alohida element va uning konteynerini bir xil boshqarishni istasangiz — Composite tanlaysiz. Agar biror og'ir yoki maxfiy obyekt oldiga 'soqchi' qo'ymoqchi bo'lsangiz — Proxy tanlaysiz."

---

## 1. Composite Pattern: Daraxtsimon Iyerarxiya

**Composite** — bu obyektlarni daraxtsimon tuzilmalarga guruhlash va alohida yakka obyekt (Leaf) hamda obyektlar guruhiga (Composite) **bir xil interfeys** orqali murojaat qilish imkonini beruvchi pattern.

```mermaid
graph TD
    RootFolder["Papkalar (Root Folder) - Composite"] --> File1["Fayl 1 (Leaf) - 5 MB"]
    RootFolder --> SubFolder["Media Papkasi - Composite"]
    
    SubFolder --> File2["Rasm.png (Leaf) - 2 MB"]
    SubFolder --> File3["Video.mp4 (Leaf) - 45 MB"]

    style RootFolder fill:#131720,stroke:#bef264,stroke-width:2px
    style SubFolder fill:#181d26,stroke:#7da2ce,stroke-width:1px
    style File1 fill:#181d26,stroke:#60a5fa,stroke-width:1px
    style File2 fill:#181d26,stroke:#60a5fa,stroke-width:1px
    style File3 fill:#181d26,stroke:#60a5fa,stroke-width:1px
```

### Swift 6 Real Kodi: Fayl Tizimi Hajmini Hisoblash
Chaqiruvchi bitta fayl yoki butun papkani tekshirayotganini bilishi shart emas. Har ikkalasi ham `getSizeInMB()` ga ega:

```swift
import Foundation

// 1. Umumiy Komponent Protokoli
public protocol FileSystemItem: Sendable {
    var name: String { get }
    func getSizeInMB() -> Double
}

// 2. Yakka Obyekt (Leaf - Barg)
public struct FileItem: FileSystemItem {
    public let name: String
    public let size: Double
    
    public init(name: String, size: Double) {
        self.name = name
        self.size = size
    }
    
    public func getSizeInMB() -> Double {
        return size
    }
}

// 3. Konteyner (Composite - Shox)
public final class FolderItem: FileSystemItem {
    public let name: String
    private var children: [any FileSystemItem] = []
    
    public init(name: String) {
        self.name = name
    }
    
    public func add(_ item: any FileSystemItem) {
        children.append(item)
    }
    
    // Rekursiv ravishda ichidagi barcha fayllar va ichki papkalar hajmini yig'adi
    public func getSizeInMB() -> Double {
        return children.reduce(0.0) { $0 + $1.getSizeInMB() }
    }
}
```

iOS ekotizimida `UIView` va uning `subviews` iyerarxiyasi Composite patternining eng yorqin namunasidir!

---

## 2. Proxy Pattern: Ishonchli Soqchi

**Proxy (Vakil)** — bu boshqa bir obyektga kirishni nazorat qiluvchi, uning o'rnini bosuvchi va qo'shimcha vazifalarni (xavfsizlik, kechiktirib yuklash, kesh) bajaruvchi pattern.

```mermaid
flowchart LR
    Client["Mijoz / ViewModel"] --> Proxy["ProtectionProxy\n(FaceID / Biometrika Tekshiruvchisi)"]
    Proxy -->|"Foydalanuvchi tasdiqlandi"| RealService["Haqiqiy Bank O'tkazma Servisi"]
    Proxy -->|"Bekor qilindi"| Reject["So'rov rad etildi (Xavfsizlik)"]

    style Proxy fill:#131720,stroke:#bef264,stroke-width:2px
    style RealService fill:#0d1f14,stroke:#4ade80,stroke-width:1px
    style Reject fill:#251014,stroke:#f87171,stroke-width:1px
```

### Proxy ning 3 Ta Asosiy Turi:
1. **Protection Proxy (Himoyachi):** Amallarni bajarishdan oldin foydalanuvchining huquqlarini (Role-Based Access Control yoki Biometrika) tekshiradi.
2. **Virtual Proxy (Kechiktiruvchi):** Og'ir obyektlarni xotiraga faqat kerak bo'lgandagina (Lazy Loading) yuklaydi.
3. **Caching Proxy (Keshlovchi):** Bir marta olingan ma'lumotni keshda saqlab, serverga qayta so'rov yuborishdan saqlaydi.

---

## 3. Real Swift 6 Kodi: Xavfsiz To'lov Himoya Proksisi

```swift
import LocalAuthentication

// 1. Asosiy Servis Protokoli
public protocol MoneyTransferService: Sendable {
    func transferFunds(amount: Double, recipient: String) async throws -> String
}

// 2. Haqiqiy Servis (Xavfli operatsiya)
public final class RealMoneyTransferService: MoneyTransferService {
    public init() {}
    
    public func transferFunds(amount: Double, recipient: String) async throws -> String {
        return "\(amount) so'm \(recipient) ga muvaffaqiyatli o'tkazildi!"
    }
}

// 3. Protection Proxy (FaceID so'rovchisi)
public final class SecureTransferProxy: MoneyTransferService {
    private let realService: RealMoneyTransferService
    
    public init(realService: RealMoneyTransferService = RealMoneyTransferService()) {
        self.realService = realService
    }
    
    public func transferFunds(amount: Double, recipient: String) async throws -> String {
        // FaceID / TouchID tekshiruvi
        let context = LAContext()
        var error: NSError?
        
        guard context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) else {
            throw TransferSecurityError.biometricsUnavailable
        }
        
        let authenticated = try await context.evaluatePolicy(
            .deviceOwnerAuthenticationWithBiometrics,
            localizedReason: "Tranzaksiyani tasdiqlash uchun FaceID kerak"
        )
        
        guard authenticated else {
            throw TransferSecurityError.authenticationFailed
        }
        
        // Faqat muvaffaqiyatli tekshiruvdan keyin haqiqiy servisga ruxsat beriladi!
        return try await realService.transferFunds(amount: amount, recipient: recipient)
    }
}

public enum TransferSecurityError: Error {
    case biometricsUnavailable
    case authenticationFailed
}
```

---

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

<details>
<summary><b>1-Savol: Swift tilidagi 'lazy var' xususiyati qaysi patternning ixcham shakli hisoblanadi?</b> (Yechimni ko'rish uchun bosing)</summary>

**Tahlil va Yechim:**
Bu **Virtual Proxy** patternining til darajasidagi mexanizmidir! `lazy var heavyData = loadData()` yozganingizda, o'zgaruvchi xotirada darhol yaratilmaydi. Faqat birinchi marta unga murojaat qilingandagina yuklanish sodir bo'ladi.
</details>

<details>
<summary><b>2-Savol: Composite patternida xotira oqishi (Retain Cycle) xavfi qayerda yuzaga keladi?</b> (Yechimni ko'rish uchun bosing)</summary>

**Tahlil va Yechim:**
Agar ichki bola elementlar (Children) o'zining ota papkasi yoki ota View'siga havola (`parent`) saqlasa: agar `parent` havolasi `weak` qilinmasa, ota va bola bir-birini kuchli (strong) ushlab turadi va butun daraxt xotiradan (Heap) o'chmay qoladi.
</details>

---

## 5. Amaliy Topshiriq (Senior Challenge)

`DynamicMenuComponent` tizimini Composite patterni asosida quring:
* `MenuItem` (oddiy bosiladigan havola) va `MenuGroup` (ichida boshqa `MenuItem`lar yoki boshqa guruhlar bo'lishi mumkin bo'lgan menyu bo'limi) yarating.
* Butun menyu iyerarxiyasini ekranda rekursiv ravishda konsolga chiroyli tabulyatsiya (`  ├── `) bilan chiqaruvchi `render()` metodini yozing!
