Azimjon Abdurasulov

07. Composite va Proxy: Fayl Tizimi va Biometrik Soqchi

🏛️ iOS Design Patterns — Mukammal Enterprise & Architecture Qo‘llanma

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.

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:

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.

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

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 MenuItemlar 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!

Markdown manba

iOS Lessons