# Senior & Staff iOS Architecture Imtihoni va Capstone Challenge

Ushbu yakuniy modulda siz iOS Design Patterns bo‘yicha to‘plagan barcha nazariy va amaliy bilimlaringizni sinovdan o‘tkazasiz. Bo‘lim ikki qismdan iborat:
1. **Senior / Lead darajasidagi 15 ta chuqur texnik intervyu savollari** (Real-world keyslar, trade-offlar va pitfalls).
2. **Capstone Architecture Challenge**: Bir nechta naqshlarni (Coordinator + Factory + Strategy + Repository + Observer + DI) uyg‘unlashtirgan to‘liq ishlaydigan **FinTech Checkout & Payment System** loyihasi.

---

## 1-Qism: Senior / Staff Intervyu Savollari va Chuqur Tahlil

O‘zingizni sinab ko‘ring! Savolga avval o‘zingiz javob berishga harakat qiling, so‘ng tahlilni ochib o‘qing.

<details>
<summary><b>1. Singleton'ni Swift 6 da thread-safe qilishning eng zamonaviy va xavfsiz yo'li qaysi? Nega global mutable static let xavfli?</b></summary>

**Javob:**
Swift'da `static let shared = MyClass()` o‘z-o‘zidan thread-safe initialization (`dispatch_once` asosida) beradi. Ammo agar `MyClass` ichida mutable property'lar (`var`) bo‘lsa, ko‘p oqimli (multithreaded) muhitda **Data Race** kelib chiqadi va Swift 6 Strict Concurrency buni compile xatosi deb hisoblaydi.

Eng toza va zamonaviy yechim — Singleton'ni `actor` sifatida e'lon qilish yoki uning ichki holatini `@MainActor` ga bog‘lash:
```swift
public actor SecureSessionManager {
    public static let shared = SecureSessionManager()
    private var token: String?
    
    private init() {}
    
    public func updateToken(_ newToken: String) {
        self.token = newToken
    }
}
```
Bu holatda Swift Concurrency kompilyatori barcha o‘qish va yozishlarni actor isolation orqali himoya qiladi va Data Race imkonsiz bo‘ladi.
</details>

<details>
<summary><b>2. Coordinator pattern'da Child Coordinator'lar xotirada qolib ketishining (Memory Leak) asosiy sababi nima va u qanday yechiladi?</b></summary>

**Javob:**
Asosiy sabab — Parent Coordinator o‘zining `childCoordinators` massivida Child ob’yektni saqlaydi, ammo Child Coordinator o‘z ishini tugatib, ekran yopilganda (masalan, UINavigationController'ning orqaga "Back" tugmasi bosilganda yoki pop bo‘lganda) parent massividan o‘chirilmaydi.

**Yechimi:**
1. Har bir Coordinator'ga `didFinish(coordinator:)` delegate yoki closure mexanizmini kiritish.
2. `UINavigationControllerDelegate` ni tinglab, ekrandan `pop` bo‘lgan `UIViewController` qaysi koordinatordan chiqqanini aniqlash va mos child'ni massivdan olib tashlash:
```swift
func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
    guard let fromVC = navigationController.transitionCoordinator?.viewController(forKey: .from),
          !navigationController.viewControllers.contains(fromVC) else { return }
    // fromVC ga tegishli child coordinatordan xalos bo'lish
}
```
</details>

<details>
<summary><b>3. Adapter va Facade o'rtasidagi asosiy konseptual farq nimada?</b></summary>

**Javob:**
- **Adapter** — bu **interfeysni o‘zgartiruvchi** naqsh. Uning maqsadi mavjud bo‘lgan bitta interfeysni ikkinchi kutilayotgan interfeysga moslashtirish (masalan, Legacy completion-handler SDK ni zamonaviy `async/await` protocoliga o‘rash). U yangi xatti-harakat qo‘shmaydi, faqat "tarjima" qiladi.
- **Facade** — bu **murakkablikni yashiruvchi** naqsh. U bitta emas, balki bir nechta mustaqil quyi tizimlarni (masalan, Audio, Bluetooth, Database, Network) bitta qulay, soddalashtirilgan interfeys orqasida birlashtiradi (`AppStartupFacade.start()`).
</details>

<details>
<summary><b>4. Repository Pattern'da "Single Source of Truth" (SSOT) nimani anglatadi va Stale-While-Revalidate qanday ishlaydi?</b></summary>

**Javob:**
SSOT (Yagona Haqiqat Manbai) — UI qatlami hech qachon "Network'dan ma'lumot oldimmi yoki Local DB'danmi?" deb o‘ylamasligi kerakligini bildiradi. UI faqat bitta manbaga — masalan, Local Database (SQLite / Realm) ga obuna bo‘ladi.

**Stale-While-Revalidate** oqimida:
1. Repository birinchi navbatda Local Cache'dagi eski (stale) ma’lumotni darhol qaytaradi (UI lahzada ochiladi).
2. Orqa fonda tarmoqdan yangi ma’lumot so‘raladi.
3. Yangi ma’lumot kelgach, u Local DB ga saqlanadi.
4. Local DB dagi o‘zgarish reaktiv tarzda (Observer / AsyncStream orqali) UI ga uzatiladi.
</details>

<details>
<summary><b>5. Delegation pattern'da protocol nega `AnyObject` dan meros olishi shart va `weak` kalit so'zi qanday rol o'ynaydi?</b></summary>

**Javob:**
Swift'da `weak` faqat Reference Type (Class) larda ishlatilishi mumkin, Value Type (Struct) larda reference count tushunchasi yo‘q. Agar protocol `: AnyObject` deb e'lon qilinmasa, kompilyator unga Struct ham kelishi mumkin deb hisoblaydi va `weak var delegate: MyDelegate?` deb yozishga ruxsat bermaydi.
`weak` yozilmasa, `Presenter -> View` va `View -> Presenter (delegate)` o‘rtasida **Strong Reference Cycle (Retain Cycle)** yuzaga keladi va ekran yopilganda ham xotiradan o‘chmaydi (ARC count hech qachon 0 ga tushmaydi).
</details>

<details>
<summary><b>6. Strategy va State pattern'larining class diagrammasi deyarli bir xil. Ularni qanday farqlash mumkin?</b></summary>

**Javob:**
Konseptual farq ularning maqsadi va holat almashishida:
- **Strategy** — biror aniq vazifani (algoritm) turli xil usullarda bajarish (masalan, to‘lovni PayPal yoki Card orqali qilish). Mijoz odatda strategiyani o‘zi tanlaydi va u butun operatsiya davomida kamdan-kam o‘zgaradi. Strategiyalar bir-biridan mustaqil.
- **State** — ob’yektning ichki holati o‘zgarganda uning xatti-harakatini to‘liq o‘zgarishi (Finite State Machine). Muhimi: holatlar o‘zlari navbatdagi holatga o‘tishni bilishi va boshqarishi mumkin (`Connecting -> Connected -> Disconnected`).
</details>

<details>
<summary><b>7. Service Locator nima sababdan ko'plab arxitektorlar tomonidan Anti-Pattern deb baholanadi?</b></summary>

**Javob:**
1. **Yashirin qaramliklar**: Ob’yektning `init`ida hech qanday parametr ko‘rinmaydi, lekin ichida `ServiceLocator.shared.get()` chaqiriladi.
2. **Kompilyatsiya xavfsizligi yo'qligi**: Agar zarur servis unutilgan bo‘lsa, kod compile bo‘ladi, ammo dastur ish paytida (runtime) kutilmaganda crash bo‘ladi.
3. **Unit test qiyinligi**: Test yozish uchun global Service Locator holatini tozalash va har bir test uchun qayta to‘ldirish zarur bo‘ladi, bu esa testlarning parallel ishlashini buzadi.
</details>

<details>
<summary><b>8. Decorator pattern Swift'da Subclassing'dan qanday ustunlik beradi?</b></summary>

**Javob:**
Subclassing (merosxo‘rlik) statik bo‘lib, compile-time'da aniqlanadi. Agar sizda 4 ta qo‘shimcha funksiya (Kesh, Log, Shifrlash, Siqish) bo‘lsa, subclassing orqali har bir kombinatsiya uchun yangi sinf yaratish talab etiladi (Class Explosion — $2^4 = 16$ ta sinf!).
Decorator esa kompozitsiya asosida ishlaydi: siz funksiyalarni dinamik ravishda bir-birining ichiga joylab (o‘rab), istalgan ketma-ketlikda yig‘ishingiz mumkin:
`Logging(Caching(Encryption(BaseService())))`.
</details>

<details>
<summary><b>9. Observer pattern'da Memory Leak kelib chiqmasligi uchun nimalarga e'tibor berish zarur?</b></summary>

**Javob:**
Agar Observer'lar kolleksiyada strong reference bilan saqlansa, ular hech qachon deallocated bo‘lmaydi. Buni hal qilish uchun:
1. `WeakBox` (weak reference o‘rovchi struktura) dan foydalanish.
2. NotificationCenter da `removeObserver()` chaqirish yoki Combine'da `AnyCancellable` ni xotiradan tozalash.
3. Swift 6 da esa zamonaviy `AsyncStream` lardan foydalanib, task bekor bo‘lganda (`onTermination`) avtomatik tozalanishini ta’minlash.
</details>

<details>
<summary><b>10. Telescoping Constructor muammosi nima va u qaysi naqsh bilan yechiladi?</b></summary>

**Javob:**
Telescoping Constructor — ob’yektda juda ko‘p ixtiyoriy (optional) parametrlar bo‘lganda, parametrlar soni oshib ketib, `init(a: b: c: d: e: f: g:)` ko‘rinishidagi o‘qib bo‘lmas konstruktorlar paydo bo‘lishi.
Bu muammo **Builder Pattern** yordamida yechiladi. Fluent API orqali faqat kerakli parametrlar zanjir ko‘rinishida o‘rnatiladi (`RequestBuilder().setURL(...).setMethod(...).build()`).
</details>

---

## 2-Qism: Capstone Architecture Challenge — FinTech Core Engine

Quyidagi topshiriq barcha o‘rganilgan naqshlarni bitta tizimda birlashtiradi.

### Loyiha Arxitekturasi (Mermaid)

```mermaid
graph TD
    subgraph UI & Navigation
        Coord[CheckoutCoordinator] -->|Boshqaradi| VC[CheckoutViewController]
    end

    subgraph Dependency Injection
        DI[DIContainer] -.->|Injects| Coord
        DI -.->|Injects| Repo[PaymentRepository]
    end

    subgraph Business Logic & Data
        VC -->|Foydalanadi| Repo
        Repo -->|Single Source of Truth| Cache[(Local SQLite / Cache)]
        Repo -->|Tarmoq orqali sinxronlash| API[RemotePaymentAPI]
    end

    subgraph Factory & Strategy
        VC -->|Tanlaydi| StratFactory[PaymentStrategyFactory]
        StratFactory -->|Yaratadi| Strat1[ApplePayStrategy]
        StratFactory -->|Yaratadi| Strat2[CreditCardStrategy]
        StratFactory -->|Yaratadi| Strat3[CryptoStrategy]
        VC -->|Ijro etadi| Exec[PaymentExecutor]
        Exec -->|Strategy orqali to'laydi| Strat1
    end

    subgraph Reactive Observer
        Rates[ExchangeRateFeed] -->|AsyncStream Observer| VC
    end
```

---

### Ishlaydigan To‘liq Swift 6 Kod Namunasi

Ushbu kodni to‘g‘ridan-to‘g‘ri Xcode Playgrounds yoki Swift loyihangizda ishga tushirishingiz mumkin:

```swift
import Foundation

// MARK: - 1. Domain Models
public struct Money: Sendable, Equatable {
    public let amount: Decimal
    public let currency: String
}

public enum PaymentResult: Sendable {
    case success(transactionID: String)
    case failure(reason: String)
}

// MARK: - 2. Strategy Pattern: To'lov Usullari
public protocol PaymentStrategy: Sendable {
    var title: String { get }
    func processPayment(amount: Money) async throws -> PaymentResult
}

public struct ApplePayStrategy: PaymentStrategy {
    public let title = "Apple Pay"
    public func processPayment(amount: Money) async throws -> PaymentResult {
        // Apple Pay tokenizatsiya va biometrik tekshiruv...
        return .success(transactionID: "APL-\(UUID().uuidString.prefix(8))")
    }
}

public struct CreditCardStrategy: PaymentStrategy {
    public let title = "Credit Card (Stripe)"
    private let cardNumber: String
    
    public init(cardNumber: String) {
        self.cardNumber = cardNumber
    }
    
    public func processPayment(amount: Money) async throws -> PaymentResult {
        return .success(transactionID: "CC-\(UUID().uuidString.prefix(8))")
    }
}

// MARK: - 3. Factory Pattern: Strategiya Yaratuvchi
public enum PaymentMethodType: Sendable {
    case applePay
    case creditCard(number: String)
}

public struct PaymentStrategyFactory {
    public static func makeStrategy(for type: PaymentMethodType) -> any PaymentStrategy {
        switch type {
        case .applePay:
            return ApplePayStrategy()
        case .creditCard(let number):
            return CreditCardStrategy(cardNumber: number)
        }
    }
}

// MARK: - 4. Observer Pattern: Valyuta Kurslari Oqimi (AsyncStream)
public final class LiveExchangeRateFeed: @unchecked Sendable {
    public static let shared = LiveExchangeRateFeed()
    private init() {}
    
    public func rateStream() -> AsyncStream<Decimal> {
        AsyncStream { continuation in
            let timer = DispatchSource.makeTimerSource()
            timer.schedule(deadline: .now(), repeating: .seconds(2))
            
            var currentRate: Decimal = 12750.0
            timer.setEventHandler {
                currentRate += Decimal(Double.random(in: -10...10))
                continuation.yield(currentRate)
            }
            
            continuation.onTermination = { _ in
                timer.cancel()
            }
            
            timer.resume()
        }
    }
}

// MARK: - 5. Repository Pattern: Offline-First To'lov Tarixi
public protocol PaymentHistoryRepository: Sendable {
    func getHistory() async -> [String]
    func record(transactionID: String) async
}

public actor LocalPaymentRepository: PaymentHistoryRepository {
    private var transactions: [String] = []
    
    public init() {}
    
    public func getHistory() -> [String] {
        return transactions
    }
    
    public func record(transactionID: String) {
        transactions.append(transactionID)
    }
}

// MARK: - 6. Coordinator Pattern: Navigatsiya
@MainActor
public protocol Coordinator: AnyObject {
    func start()
}

@MainActor
public final class CheckoutCoordinator: Coordinator {
    private let repository: any PaymentHistoryRepository
    
    public init(repository: any PaymentHistoryRepository) {
        self.repository = repository
    }
    
    public func start() {
        print("🧭 CheckoutCoordinator: Checkout oqimi boshlandi.")
    }
    
    public func completeCheckout(transactionID: String) async {
        await repository.record(transactionID: transactionID)
        print("🎉 Checkout muvaffaqiyatli yakunlandi! ID: \(transactionID)")
    }
}

// MARK: - 7. Asosiy Orkestratsiya (Amalda Ishga Tushirish)
@main
struct CapstoneRunner {
    static func main() async {
        print("🚀 FinTech Engine ishga tushmoqda...")
        
        let repository = LocalPaymentRepository()
        let coordinator = await CheckoutCoordinator(repository: repository)
        await coordinator.start()
        
        // 1. Factory orqali strategiya tanlash
        let method = PaymentMethodType.applePay
        let strategy = PaymentStrategyFactory.makeStrategy(for: method)
        print("💳 Tanlangan to'lov usuli: \(strategy.title)")
        
        // 2. To'lovni amalga oshirish
        let cartTotal = Money(amount: 150.00, currency: "USD")
        do {
            let result = try await strategy.processPayment(amount: cartTotal)
            switch result {
            case .success(let txID):
                await coordinator.completeCheckout(transactionID: txID)
            case .failure(let reason):
                print("❌ Xatolik: \(reason)")
            }
        } catch {
            print("❌ Tizim xatosi: \(error)")
        }
        
        // 3. Repository holatini tekshirish
        let history = await repository.getHistory()
        print("📜 Saqlangan tranzaksiyalar: \(history)")
    }
}
```

---

## 🏆 Tabriklaymiz!

Siz **iOS Design Patterns — Mukammal Enterprise & Architecture Qo‘llanma** modulini to‘liq yakunladingiz! 

Siz endi:
- Har bir naqsh qachon kerak va qachon **anti-pattern**ga aylanishini bilasiz;
- Xotira boshqaruvi (ARC, Retain Cycles) va Swift 6 Concurrency talablariga mos kod yoza olasiz;
- Massive View Controller'larni yo‘q qilib, modulli, testlanuvchi va kengayuvchan korporativ tizimlar qura olasiz.
