Published on

Ko'rinish logikasini biznes logikasidan ajratish

Authors

10.1 darsda muammoni ko'rdingiz. Endi uni tuzatish vaqti. Birinchi vosita β€” view model: biznes logikangizni, ma'lumot almashtirish va biznes holatini saqlaydigan alohida Swift turi.

Ko'rinishingiz vazifasi soddalashadi: view modeldan o'qish va u aytganini ko'rsatish.

Restoran metafori: view β€” zal (mijoz ko'radi va muloqot qiladi). View modeli β€” oshxona (haqiqiy ish). Mijozlar oshxonaga kirib o'zlari ovqat pishirishiga yo'l qo'yilmaydi. Buyurtma berishadi β€” oshxona qolganini bajaradi.

Oldin va keyin

// ❌ OLDIN β€” Hamma narsa viewda
struct VazifaKorinishi: View {
    @State private var vazifalar: [String] = []
    @State private var yangiVazifaMatni = ""
    @State private var xatoXabar: String? = nil

    var body: some View {
        VStack {
            TextField("Yangi vazifa", text: $yangiVazifaMatni)
            Button("Qo'shish") {
                let tozalangan = yangiVazifaMatni.trimmingCharacters(in: .whitespaces)
                guard !tozalangan.isEmpty else {
                    xatoXabar = "Vazifa bo'sh bo'lishi mumkin emas."
                    return
                }
                vazifalar.append(tozalangan)
                yangiVazifaMatni = ""
            }
            if let xato = xatoXabar { Text(xato).foregroundStyle(.red) }
            List(vazifalar, id: \.self) { Text($0) }
        }
    }
}
// βœ… KEYIN β€” Biznes logikasi view modelga ko'chirildi

// @Observable makrosi sinfni avtomatik kuzatiladigan qiladi
// Ko'rinishlar xususiyat o'zgarganda qayta render qiladi
@Observable
class VazifaKorinishiModeli {
    // Nashr qilinadigan xususiyatlar β€” bular o'zgarganda viewlar yangilanadi
    var vazifalar: [String] = []
    var xatoXabar: String? = nil

    // Barcha validatsiya va o'zgartirish logikasi bu yerda β€” viewdan uzoq
    func vazifaQoshish(_ matn: String) {
        let tozalangan = matn.trimmingCharacters(in: .whitespaces)
        guard !tozalangan.isEmpty else {
            xatoXabar = "Vazifa bo'sh bo'lishi mumkin emas."
            return
        }
        guard tozalangan.count <= 100 else {
            xatoXabar = "Vazifa juda uzun."
            return
        }
        vazifalar.append(tozalangan)
        xatoXabar = nil
    }
}

// Ko'rinish endi yengil β€” faqat UI ni boshqaradi
struct VazifaKorinishi: View {
    // @State view modelni yaratadi va egallaydi
    @State private var korinishiModeli = VazifaKorinishiModeli()
    @State private var yangiVazifaMatni = ""

    var body: some View {
        VStack {
            TextField("Yangi vazifa", text: $yangiVazifaMatni)
            Button("Qo'shish") {
                // Ko'rinish ishni bajarishni buyuradi β€” o'zi bajarmaydi
                korinishiModeli.vazifaQoshish(yangiVazifaMatni)
                yangiVazifaMatni = ""
            }
            if let xato = korinishiModeli.xatoXabar {
                Text(xato).foregroundStyle(.red)
            }
            List(korinishiModeli.vazifalar, id: \.self) { Text($0) }
        }
    }
}
QatorVazifasi
@ObservableSinfni avtomatik kuzatiladigan qiladi. Ko'rinishlar qaysi xususiyatlarni o'qishini kuzatadi va faqat ular o'zgarganda qayta render qiladi.
class VazifaKorinishiModeliSinf, struct emas β€” reference tur. Ko'p ko'rinish bitta modelni ulashishi mumkin. Sinf @Observable uchun zarur.
func vazifaQoshish(_ matn: String)Barcha validatsiya va o'zgartirish logikasi nomlangan, sinovdan o'tkazilishi mumkin funksiyada. Ko'rinish chaqiradi, bajaradi.
@State private var korinishiModeli = VazifaKorinishiModeli()View modeli namunasini yaratadi va egallaydi. @Observable sinf uchun @State to'g'ri.

Ko'p viewda ulashish

// View modeli bir necha ko'rinishga o'tkazilishi mumkin
struct AsosiyKorinish: View {
    @State private var model = VazifaKorinishiModeli()

    var body: some View {
        TabView {
            VazifaRo'yxatiKorinishi(model: model)
                .tabItem { Label("Vazifalar", systemImage: "list.bullet") }
            VazifaStatistikasi(model: model)
                .tabItem { Label("Statistika", systemImage: "chart.bar") }
        }
    }
}

// Ikkala ko'rinish ham bitta model namunasini ko'radi
struct VazifaRo'yxatiKorinishi: View {
    var model: VazifaKorinishiModeli
    // ...
}

Tezkor ma'lumotnoma

SintaksisVazifasi
@Observable class MeningModelim { }Sinfni avtomatik kuzatiladigan qiladi
var xususiyat: TurKo'rinishlar o'qishda kuzatiladi va o'zgarganda yangilanadi
func biznesIshi(...)Ko'rinishdan ajralgan biznes logikasi
@State private var model = Model()View modeli namunasini yaratadi va boshqaradi
model.funksiya()Ko'rinish ishni bajarishni buyuradi

🎯 Topshiriq: view modelga ko'chirish

10.1 darsdan eng katta ko'rinishingizni oling. @Observable sinf yarating. Barcha validatsiya va o'zgartirish logikasini u yerga ko'chiring. Ko'rinishda faqat @State private var model = Model() va UI kodi qolsin. Preview va simulyatorda tekshiring β€” xuddi oldingiday ishlashi kerak.

Buy mea coffee