Uygun iOS Mimarisi nasıl seçilir (Bölüm 2)
MVC, MVP, MVVM, VIPER veya VIP
Burada birinci bölüme danışabilirsiniz.
Ana iOS Mimarileri
Kısa bir bakış.
MVC
MVC katmanları aşağıdaki gibidir:
M: İş Mantığı, Ağ Katmanı ve Veri Erişim Katmanı
V: UI Katmanı (UIKit şeyler, Storyboard'lar, Xibs)
C: Model ve Görünüm arasındaki arabuluculuğu koordine eder.
MVC'yi anlamak için onun icat edildiği bağlamı anlamamız gerekir. MVC, Görüntüleme durumunun olmadığı eski Web geliştirme günlerinde icat edildi. Eski zamanlarda, her zaman web sitesinde görsel bir değişikliğe ihtiyaç duyduğumuzda, tarayıcı tüm HTML'yi yeniden yükler. O zaman, korunan ve korunan görüş durumu kavramı yoktu.
Örneğin, aynı HTML dosyası, PHP ve veritabanı erişimi içinde karışık bazı geliştiriciler vardı. Bu nedenle MVC'nin ana motivasyonu View katmanını Model katmanından ayırmaktı. Bu, Model katmanının test edilebilirliğini arttırmıştır. Sözde MVC'de, Görünüm ve Model katmanı birbirleri hakkında hiçbir şey bilmemelidir. Bunu mümkün kılmak için, Controller adlı bir aracı katman icat edildi. Bu uygulanan SRP idi.
MVC döngüsünün bir örneği:
- Görünüm Katmanındaki bir kullanıcı eylemi / etkinliği (örn: Eylemi Yenile) ateşlendi ve bu eylem Denetleyiciye iletildi
- Model Katmanına veri soran Denetleyici
- İade verilerini Denetleyiciye modelleyin
- Denetleyici, Görünüm için durumunu Yeni Verilerle güncellediğini söyledi
- Durumunu güncelle
Apple MVC
İOS'ta, Görünüm Kontrolörü UIKit ve yaşam döngüsü görünümüne bağlanmıştır, bu nedenle saf MVC değildir. Bununla birlikte, MVC tanımında, Kontrolörün belirli bir Görünümü veya Uygulamayı bilmediğini söyleyecek hiçbir şey yoktur. Temel amacı, Model katmanını View katmanından sorumlulukları ayırmak, böylece onu yeniden kullanabilmemiz ve Model katmanını yalıtılmış bir şekilde test etmemizdir.
ViewController, Görünümü içerir ve Modelin sahibidir. Buradaki sorun, ViewController'daki denetleyici kodunu ve görünüm kodunu yazmak için kullanılır.
MVC, genellikle Massive View Controller problemini yaratır, ancak bu sadece yeterli karmaşıklığa sahip uygulamalarda olur ve ciddi bir şey haline gelir.
Geliştiricinin Görünüm Denetleyiciyi daha yönetilebilir hale getirmek için kullanabileceği bazı yöntemler vardır. Bazı örnekler:
- VC mantığını, tablo görünümü yöntemleri veri kaynağı gibi diğer sınıflar için ayıklamak ve temsilci tasarım desenini kullanarak diğer dosyalar için temsilci seçmek.
- Kompozisyonla birlikte sorumlulukların daha belirgin bir şekilde ayrılmasını sağlayın (örneğin, VC'yi çocuk görünümü kontrol cihazlarına bölme).
- VC'de navigasyon mantığını uygulama sorumluluğunu ortadan kaldırmak için koordinatör tasarım desenini kullanın.
- Mantığı kaplayan ve veri modelini son kullanıcıya sunulan verileri temsil eden bir veri çıktısına dönüştüren bir DataPresenter sarmalayıcı sınıfı kullanın.
MVC vs MVP
MVC ileriye doğru bir adımdı, ancak yine de bazı şeylerin yokluğu ya da sessizliği ile işaretlendi.
Bu arada, World Wide Web büyüdü ve geliştiricilerin topluluğundaki birçok şey gelişti. Örneğin, programcılar Ajax'ı kullanmaya başladı ve bir kerede HTML sayfasının tamamı yerine sadece sayfa parçalarını yükledi.
MVC'de, Kontrolörün belirli bir Görünüm (devamsızlık) uygulamasını bilmemesi gerektiğini gösteren hiçbir şey olmadığını düşünüyorum.
HTML, Görünüm katmanının bir parçasıydı ve çoğu vaka sikiş olarak aptaldı. Bazı durumlarda, yalnızca kullanıcıdan gelen olayları alır ve GUI'nin görsel içeriğini görüntüler.
Web sayfalarının bölümleri bölümlere yüklenmeye başladığında, bu bölümleme Görünüm durumunun sürdürülmesi yönünde ve sunum mantığı sorumluluk ayrımı için daha fazla ihtiyaç duyulmasına neden oldu.
Sunum mantığı, UI'nin nasıl gösterilmesi gerektiğini ve UI öğelerinin birlikte nasıl etkileşimde bulunduğunu kontrol eden mantıktır. Bir örnek, bir Yükleme Göstergesinin ne zaman / animate göstermeye başlaması ve ne zaman / animate göstermeyi durdurması gerektiğinin kontrol mantığıdır.
MVP ve MVVM'de Görüntü Katmanı, içinde herhangi bir mantık veya zeka olmadan sikik olarak aptal olmalı ve iOS'ta Görüntü Denetleyici, Görüntü Katmanının bir parçası olmalıdır. Görünümün aptal olduğu gerçeği, sunum mantığının bile Görünüm katmanının dışında kaldığı anlamına gelir.
MVC'nin sorunlarından biri, sunum mantığının nerede kalması gerektiği konusunda net olmamasıdır. O sadece bu konuda sessiz. Sunum mantığı Görünüm katmanında mı yoksa Model Katmanında mı olmalıdır?
Modelin rolü yalnızca "ham" verileri sağlamaksa, Görünüm'deki kodun şu şekilde olacağı anlamına gelir:
Aşağıdaki örneği düşünün: adımız ve soyadınız olan bir Kullanıcımız var. Görünümde, kullanıcı adını “Soyadı, Adı” (örneğin, “Flores, Tiago”) olarak görüntülememiz gerekir.
Modelin rolü “ham” verileri sağlamaksa, Görünüm'deki kodun şu anlama geleceği anlamına gelir:
firstName = userModel.getFirstName () işlevine izin verin lastName let = userModel.getLastName () nameLabel.text = lastName + “,“ + firstName
Yani bu, UI mantığını kullanmanın View'un sorumluluğudur. Ancak bu, kullanıcı arabirimi mantığını birim sınaması için imkansız kılar.
Diğer yaklaşım, Modelin yalnızca görüntülenmesi gereken verileri göstererek herhangi bir iş mantığını Görünümden gizlemektir. Ama sonra, hem iş hem de kullanıcı arayüzü mantığını ele alan Modellerle sonuçlanıyoruz. Birim test edilebilir olur, ancak daha sonra Model sona erer, dolaylı olarak Görünüme bağlıdır.
let name = userModel.getDisplayName () nameLabel.text = isim
MVP bu konuda net ve sunum mantığı Presenter Layer'da kalıyor. Bu, Presenter katmanının test edilebilirliğini arttırır. Artık Model ve Sunum Katmanı kolayca test edilebilir.
Normalde MVP uygulamalarında, Görünüm bir arayüz / protokolün arkasına gizlenir ve Presenter'daki UIKit'e referans olmamalıdır.
Akılda tutulması gereken bir başka şey, geçiş bağımlılıklarıdır.
Denetleyicinin bir bağımlılık olarak İş Katmanı varsa ve İş Katmanının bir bağımlılık olarak Veri Erişim Katmanı varsa, Denetleyicinin Veri Erişim Katmanı için geçişli bir bağımlılığı vardır. MVP uygulamaları normalde tüm katmanlar arasında bir sözleşme (protokol) kullandığından, geçişli bağımlılıkları yoktur.
Farklı katmanlar ayrıca farklı nedenlerle ve farklı oranlarda değişir. Dolayısıyla bir katmanı değiştirdiğinizde bunun diğer katmanlardaki ikincil etkilere / sorunlara neden olmasını istemezsiniz.
Protokoller sınıflardan daha kararlıdır. Protokoller uygulama detaylarına ve sözleşmelere sahip olmadığından, diğer katmanları etkilemeden bir katmanın uygulama detaylarını değiştirmek mümkündür.
Böylece sözleşmeler (protokoller) katmanlar arasında ayrışma yaratır.
MVP vs MVVM arası
MVP ve MVVM arasındaki ana farklardan biri, MVP'de Presenter'ın Görünümle arayüzler üzerinden iletişim kurması ve MVVM'de Görünümün veri ve olay değişikliklerine yönelik olmasıdır.
MVP'de, Presenter ile Arayüzler / Protokolleri kullanarak Görünüm arasında manüel bağlanma yapıyoruz.
MVVM'de RxSwift, KVO gibi bir şey kullanarak otomatik veri bağlama yapıyoruz ya da jenerik ve kapanma mekanizmasını kullanıyoruz.
MVVM'de ViewModel ve View arasında bir sözleşmeye (örneğin: java interface / iOS protokolü) ihtiyaç duymazız çünkü genellikle Gözlemci Tasarım Örüntüsüyle iletişim kurarız.
MVP, Temsilci Düzenini kullanır çünkü Presenter Katmanı, Görünüm Katmanına sipariş verdiğinden, yalnızca arabirim / protokol imzası olsa bile, Görünüm hakkında bir şeyler bilmesi gerekir. Notification Center ve TableView Delegates arasındaki farkı düşünün. Bildirim Merkezi'nin bir iletişim kanalı oluşturmak için arayüzlere ihtiyacı yoktur, ancak TableView Delegates, sınıfların uygulaması gereken bir protokol kullanır.
Bir yükleme göstergesinin sunum mantığını düşünün. MVP'de sunucu ViewProtocol.showLoadingIndicator işlevini yerine getirir. MVVM'de ViewModel'de bir isLoading özelliği olabilir. Otomatik veri bağlama yoluyla Görüntüleme katmanı, bu özelliğin ne zaman değiştiğini ve yenilendiğini algılar. Sunum yapan kişi sipariş verdiğinden, MVP MVVM'den daha zorunludur.
MVVM, doğrudan siparişlerden daha fazla veri değişikliği hakkındadır ve veri değişiklikleri ile güncellemeleri görüntüleme arasında ilişki kurarız. MVVM ile birlikte RxSwift ve fonksiyonel reaktif programlama paradigmasını kullanırsanız, kodu daha az zorunlu ve daha açıklayıcı hale getirdik.
MVVM'nin MVP'ye göre test edilmesi daha kolaydır, çünkü MVVM, bileşenler arasında veri ayrıştırılmış bir şekilde aktaran Observer Design Pattern'i kullanır.
Böylece sadece görünümdeki ve Sunumcu arasındaki iletişimi test etmek için kullanılan yöntemlerle alay etmek yerine sadece iki nesneyi karşılaştırarak verilerdeki değişikliklere bakarak test edebiliriz.
Not: Çok fazla büyümesini sağlayan makaleyle ilgili bazı güncellemeler yaptım, bu yüzden makaleyi üç bölüme ayırmak gerekiyordu. Burada üçüncü kısmı okuyabilirsiniz.
İkinci bölüm burada sona eriyor. Tüm geribildirim açığız. Üçüncü bölüm, VIPER, VIP, Reaktif Programlama, Değişim, Sınırlamalar ve Bağlamsal Anlam hakkında konuşacak.