# 11. Behavioral: Memento va Iterator Pattern

> "Agar foydalanuvchi 20 ta maydondan iborat anketani to'ldirayotganda kutilmaganda ilovadan chiqib ketsa va qayta kirganda hamma narsa o'chib ketganini ko'rsa — u ilovani o'chirib tashlaydi. Memento inkapsulyatsiyani buzmasdan holatni 'suratga' oladi. Iterator esa millionlab yozuvlarni RAM ni portlatmasdan oqimda o'qish imkonini beradi."

---

## 1. Memento Pattern: Obyekt Holatini Saqlash va Tiklash

**Memento (Yodgorlik / Snapshot)** — bu obyektning ichki maxfiy ma'lumotlarini (Encapsulation) tashqi dunyoga oshkor qilmagan holda, uning o'sha lahzadagi holatini saqlab qolish va kerak bo'lganda o'tmishdagi shu holatga to'liq qaytarish imkonini beruvchi pattern.

```mermaid
sequenceDiagram
    autonumber
    participant Form as RegistrationForm (Originator)
    participant Caretaker as DraftManager (Caretaker)

    Note over Form: Foydalanuvchi ma'lumot kiritmoqda...
    Form->>Form: makeSnapshot() -> FormMemento
    Form->>Caretaker: save(memento) (Diskka yozildi)
    
    Note over Form: 💥 Ilova yopildi yoki xotiradan o'chirildi!
    Note over Form: Yangi seans boshlandi...
    Caretaker->>Form: restore(memento)
    Note over Form: Barcha maydonlar 100% tiklandi!
```

---

## 2. Real Swift 6 Kodi: Anketani Saqlovchi Memento

Swift'da `Codable` protokoli Memento patternini amalga oshirishning eng toza va zamonaviy usulidir:

```swift
import Foundation

// 1. Originator (Holati saqlanadigan asosiy obyekt)
public final class JobApplicationForm {
    public var fullName: String = ""
    public var expectedSalary: Int = 0
    public var skills: [String] = []
    
    public init() {}
    
    // Memento (O'sha lahzadagi holat surati)
    public struct Memento: Codable, Sendable {
        fileprivate let name: String
        fileprivate let salary: Int
        fileprivate let skillsList: [String]
        fileprivate let timestamp: Date
    }
    
    /// Hozirgi holatni suratga olish
    public func createSnapshot() -> Memento {
        return Memento(
            name: fullName,
            salary: expectedSalary,
            skillsList: skills,
            timestamp: Date()
        )
    }
    
    /// Eski suratdan holatni qayta tiklash
    public func restore(from memento: Memento) {
        self.fullName = memento.name
        self.expectedSalary = memento.salary
        self.skills = memento.skillsList
        print("✅ Forma tiklandi! (Saqlangan vaqti: \(memento.timestamp))")
    }
}

// 2. Caretaker (Suratlarni diskda saqlovchi)
public final class DraftManager {
    private let userDefaults = UserDefaults.standard
    private let draftKey = "job_application_draft"
    
    public func saveDraft(_ memento: JobApplicationForm.Memento) {
        if let encoded = try? JSONEncoder().encode(memento) {
            userDefaults.set(encoded, forKey: draftKey)
        }
    }
    
    public func loadDraft() -> JobApplicationForm.Memento? {
        guard let data = userDefaults.data(forKey: draftKey),
              let memento = try? JSONDecoder().decode(JobApplicationForm.Memento.self, from: data) else {
            return nil
        }
        return memento
    }
}
```

---

## 3. Iterator Pattern: Millionlab Yozuvlarni RAM ni To'ldirmasdan O'qish

**Iterator** — bu to'plamning (Collection, List, Tree) ichki tuzilishini oshkor qilmasdan, uning elementlarini birma-bir ketma-ket aylanib chiqish (Traverse) imkonini beruvchi pattern.

```mermaid
flowchart LR
    Source["Og'ir 500 MB CSV Fayl\n(1,000,000 ta qator)"] --> Iterator["LargeFileIterator\n(IteratorProtocol)"]
    Iterator -->|"next() chaqirilganda"| RAM["Faqat 1 ta qator RAM'ga yuklanadi\n(Xotira sarfi: atigi 2 KB!)"]
    RAM --> Worker["Qayta ishlovchi prosessor"]

    style Source fill:#251014,stroke:#f87171,stroke-width:1px
    style Iterator fill:#131720,stroke:#bef264,stroke-width:2px
    style RAM fill:#0d1f14,stroke:#4ade80,stroke-width:1px
```

### Swift'ning `IteratorProtocol` va `Sequence`:
Agar siz 1 millionta qatorni birdan `lines = try String(contentsOf: file).components(separatedBy: "\n")` qilib o'qisangiz — ilovangiz **Jetsam Out-Of-Memory Crash** bilan o'ladi!
Iterator esa elementlarni **faqat so'ralgandagina (Lazy Streaming)** bittalab yuklaydi:

```swift
import Foundation

public struct InfiniteIDGenerator: Sequence, IteratorProtocol {
    private var currentID: Int = 1
    
    public mutating func next() -> Int? {
        let id = currentID
        currentID += 1
        return id
    }
}

// Ishlatilishi:
var generator = InfiniteIDGenerator()
print(generator.next()!) // 1
print(generator.next()!) // 2
print(generator.next()!) // 3
```

---

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

<details>
<summary><b>1-Savol: Memento va Command (Undo/Redo) o'rtasida qanday bog'liqlik bor?</b> (Yechimni ko'rish uchun bosing)</summary>

**Tahlil va Yechim:**
Ular juda ko'p hollarda birga ishlatiladi! `Command` obyekti biror amalni bajarishdan oldin Originator'dan `createSnapshot()` orqali Memento olib, o'zining ichida saqlab qo'yadi. Agar foydalanuvchi "Undo" qilsa, Command o'sha saqlab qo'yilgan Mementoni Originator'ga qaytaradi (`restore(memento)`).
</details>

<details>
<summary><b>2-Savol: Swift'dagi 'for item in items' sikli qaysi pattern asosida ishlaydi?</b> (Yechimni ko'rish uchun bosing)</summary>

**Tahlil va Yechim:**
Bu 100% **Iterator Pattern**idir! Swift tili har qanday `Sequence` ni ko'rganda, orqa fonda uning `makeIterator()` metodini chaqiradi va `while let item = iterator.next()` siklini yurgizadi.
</details>

---

## 5. Amaliy Topshiriq (Senior Challenge)

`UserPreferencesOriginator` sinfini quring:
* Unda `theme: String`, `fontSize: Double`, `notificationsEnabled: Bool` maydonlari bo'lsin.
* Foydalanuvchi sozlamalarni o'zgartirganda "Oldingi holatga qaytish" (Revert) imkonini beruvchi Memento arxitekturasini yarating!
