Modülerlik, uygulamanın bağımsız modüllerden oluşturulduğu ve her modülün tek bir işlevden sorumlu olduğu bir ilkedir. Android Developers'a göre, modüllere ayırma paralel derleme sayesinde derlemeyi hızlandırır ve ekiplerin uygulamanın farklı bölümleri üzerinde bağımsız olarak çalışmasına olanak tanır. Modüler mimari, düzinelerce geliştiricisi olan büyük mobil projeler için standart haline gelmiştir.
Önemli Noktalar
Modülerlik, bir uygulamanın gevşek bağlı modüllerden oluştuğu ve her modülün genel bir arayüz aracılığıyla kesin olarak tanımlanmış bir işlev sağladığı bir kod düzenleme yoludur. Tüm sınıfların tek bir projede bulunduğu monolitik mimarinin aksine, modüler yaklaşım kodu fiziksel olarak bağımsız derleme birimlerine ayırır.
Modülerliğin temel amacı karmaşıklık yönetimidir. Bir geliştirici, tüm kod tabanını aklında tutmadan tek bir modüle odaklanabilir. Her modülün kendi sorumluluk alanı vardır ve diğerlerinden bağımsız olarak geliştirilebilir, test edilebilir ve dağıtılabilir. Bu, 10'dan fazla geliştiricinin olduğu projelerde özellikle değerlidir; monolit üzerinde paralel çalışma sık sık birleştirme çakışmalarına yol açar.
Modülerliği katmanlı mimariden ayırt etmek önemlidir. Katmanlar (Presentation, Domain, Data) kodu teknik kriterlere göre ayırırken, modüller işlevsel kriterlere göre ayırır. Bir “Kullanıcı Profili” modülü kendi iç katmanlarını içerebilir. Pratikte, modüler yaklaşım ve katmanlı mimari birleştirilir: her modülün kendi üç katmanlı yapısı vardır.
Özellik modülleri en popüler modül türüdür. Her ekran veya ilgili ekran grubu kendi modülüne ayrılır: Onboarding, Profile, Settings, Feed. Bir özellik modülü, özelliğin çalışması için gereken her şeyi içerir: UI, iş mantığı, veri katmanı. Modül sınırları korunur — diğer özellikler iç sınıflarına erişemez.
Çekirdek modüller ortak altyapıyı içerir: ağ bağlantısı, veritabanı, analitik, tasarım sistemi. Özellik modüllerine bağlı değildirler, ancak özellik modülleri onlara bağlıdır. Bu ayrım, analitik SDK'sını değiştirmenin ağ katmanını etkilemeyeceğini ve bunun tersini garanti eder. Çekirdek modüller, kod tekrarı olmadan özellikler arasında yeniden kullanılır.
Paylaşılan modüller, birden çok özellik tarafından kullanılan kodu içerir: veri modelleri, yardımcı programlar, sabitler, özel Görünümler. Paylaşılan modüllerin ana sorunu, zamanla heterojen kodun biriktiği bir “karma modül” haline gelme riskidir. Kural: paylaşılan bir modülün net bir teması olmalıdır, örneğin “shared-ui” veya “shared-models”.
Android'de paylaşılan modüller genellikle lib ön ekli kitaplıklara ayrılır: lib-network, lib-database, lib-ui-components. iOS'te aynı işlev, Workspace içindeki dahili Swift Packages tarafından gerçekleştirilir. Pratikte ekipler, derlemeyi zorlaştıran aşırı bağımlılık ağı oluşturmamak için paylaşılan modül sayısını 3–5 ile sınırlar.
Ayrı test modülleri, tüm test paketini çalıştırmadan yalnızca değiştirilen modül için testlerin çalıştırılmasına olanak tanır. Bu, CI/CD boru hattı süresini saatlerden dakikalara düşürür. Modül düzeyinde izolasyon, derleme düzeyinde SoC'yi sağlar: bir ağ katmanı modülü, testlerinde yanlışlıkla UI kitaplıklarını içe aktaramaz.
Her modülün açıkça tanımlanmış bir genel API'si olmalıdır. Android'de bu, erişim değiştiricileri ve Gradle'da api ve implementation aracılığıyla elde edilir. iOS'te, public/internal erişim değiştiricileri ve Package.swift aracılığıyla yönetilen bağımlılıklar aracılığıyla elde edilir. Görünürlüğü gerekli minimuma indirmek, modüler tasarımın önemli bir uygulamasıdır.
Gradle modüler mimariyi yerel olarak destekler: her modül, kendi build.gradle dosyasına sahip ayrı bir derleme birimidir. Android projeleri, bir uygulama modülü (app) ve birkaç kitaplık modülünün birleşimini kullanır. Kitaplık modülleri uygulama olarak çalıştırılamaz ancak bir depoya AAR olarak yayınlanabilir.
Gradle'ın önemli bir özelliği, bağımsız modüllerin paralel derlenmesidir. A, B ve C modülleri birbirine bağımlı değilse, Gradle bunları tüm CPU çekirdeklerini kullanarak aynı anda derler. 20'den fazla modülü olan projelerde bu, tam derlemeyi 15 dakikadan 3–5 dakikaya düşürür. Değiştirilen bir modülün artımlı derlemesi saniyeler sürer.
Gradle, modüller arasında iki tür bağımlılık sağlar: api (geçişli) ve implementation (geçişsiz). Fark, modülerlik için son derece önemlidir: implementation, geçişli bağımlılıkları modül tüketicilerinden gizler. :profile modülü, implementation aracılığıyla :networking kullanıyorsa, :profile tüketicileri :networking'i bilmez ve ona erişemez.
// settings.gradle — modül bildirimi
include ':app'
include ':feature:profile'
include ':feature:settings'
include ':core:network'
include ':core:database'
// build.gradle feature/profile — modül bağımlılıkları
dependencies {
implementation project(':core:network')
implementation project(':core:database')
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0'
}
Kod, modüler bir Android projesinin yapısını gösterir. Settings.gradle tüm modülleri listeler ve her özellik modülünün build.gradle'ı yalnızca ihtiyaç duyduğu çekirdek modülleri belirtir. Derleme sistemi, geçişli bağımlılıkları otomatik olarak çözer ve modülleri doğru sırada derler.
Swift Package Manager (SPM) 2019'dan beri iOS'te standart modülerlik aracıdır. SPM, uygulamayı Swift Packages'a bölmeye olanak tanır; her biri bir kitaplık veya yürütülebilir dosya olabilir. Bir Package, Package.swift aracılığıyla modülleri (hedefler) ve bağımlılıklarını tanımlar. SPM, Xcode'a entegredir ve ek araç gerektirmez.
CocoaPods, üçüncü taraf kitaplıklar için ana bağımlılık yöneticisi olmaya devam etmektedir. Podfile ve Podspec modüler yapıyı tanımlar ve CocoaPods ayrı pod projeleriyle bir çalışma alanı oluşturur. Kendi proje modülerlikleri için ekipler giderek SPM'yi tercih etmektedir çünkü Xcode'a entegredir ve kurulum gerektirmez.
iOS modülerliğinde erişim kontrolü önemli bir rol oynar: public, package, internal, fileprivate ve private. Bir modül, yalnızca diğer modüller tarafından erişilebilir olması gereken türleri yayınlar. İç uygulama ayrıntıları, internal ve private değiştiricilerinin arkasında gizlenir. Bu, modüller arasında gizli bağımlılıkları önler.
// Package.swift — iOS projesinin modüler yapısı
let package = Package(
name: "MyApp",
platforms: [.iOS(SupportedPlatform.iOSVersion.v17)],
products: [
.library(name: "ProfileFeature", targets: ["ProfileFeature"]),
.library(name: "NetworkCore", targets: ["NetworkCore"]),
],
dependencies: [
.package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.9.0")
],
targets: [
.target(name: "ProfileFeature", dependencies: ["NetworkCore"]),
.target(name: "NetworkCore", dependencies: ["Alamofire"]),
]
)
Package.swift iki kitaplık ürünü bildirir: ProfileFeature ve NetworkCore. ProfileFeature, NetworkCore'a bağlıdır ancak Alamofire'ın varlığından haberdar değildir — NetworkCore içinde gizlidir. Bu tür bir izolasyon, modül düzeyinde SoC'nin doğrudan bir uygulamasıdır: HTTP istemcisindeki değişiklikler ProfileFeature'ın yeniden derlenmesini gerektirmez.
Modülerliğin ana avantajı geliştirme hızıdır. Ekipler, kod çakışması olmadan farklı modüller üzerinde paralel olarak çalışır. CI/CD boru hattı yalnızca değiştirilen modülleri derler ve yalnızca onların testlerini çalıştırır. Geri bildirim süresi azalır ve sürüm sıklığı artar. Spotify, Uber ve Airbnb, 2–3 kat metrik iyileştirme ile modüler mimariye geçiş yapan vaka çalışmaları yayınladı.
İkinci avantaj hata izolasyonudur. Aralarında doğrudan bağımlılık yoksa Profile modülündeki bir hata Payments modülünü etkilemez. Bu, yüksek riskli işlevselliğe (ödemeler, tıbbi veriler) sahip uygulamalarda özellikle önemlidir; ilgisiz bir ekrandaki hata, kritik işlevselliğin yayınlanmasını engellememelidir.
Ana zorluk bağımlılık yönetimidir. Kötü tasarımla, bir modülün değiştirilmesinin düzinelerce diğerinin basamaklı olarak yeniden derlenmesine neden olduğu bir modül grafiği ortaya çıkar. Çözüm, döngüsüzlük kuralını izlemektir: modül bağımlılık grafiği, yönlendirilmiş döngüsel olmayan bir grafik (DAG) olmalıdır. Gradle Module Graph Assert gibi araçlar, derleme zamanında döngüleri tespit etmeye yardımcı olur.
İkinci zorluk başlangıç kurulum süresinin artmasıdır. Modüler bir mimari oluşturmak, proje başlatma aşamasında daha fazla zaman gerektirir. 1–3 geliştiricili küçük projeler, paralelleştirme için gerçek bir ihtiyaç olmadan modül sınırlarını korumak için zaman harcayarak modülerlikten fayda sağlayamayabilir. Çözüm, bir monolit ile başlamak ve ekip büyüdükçe modülleri ayırmaktır.
Feature-first yaklaşımı modülleri işlevselliğe göre gruplandırır: her ekran veya ekran grubu ayrı bir modül haline gelir. Layer-first yaklaşımı kodu teknik kriterlere göre ayırır: UI, iş mantığı ve veri için ayrı modüller. Pratikte çoğu ekip, çekirdek modüllerle feature-first'ı seçer — bu daha iyi izolasyon ve net proje navigasyonu sağlar.
Yaklaşımlar arasındaki seçim, ekip büyüklüğüne ve işlev öngörülebilirliğine bağlıdır. Projede hangi ekranların olacağını tam olarak biliyorsanız, feature-first her geliştiricinin kendi modülünden sorumlu olmasını sağlar. İşlevsellik sık sık değişiyor ve ekranlar arasında örtüşüyorsa, layer-first farklı özellikler arasında kodun yeniden kullanılmasında daha fazla esneklik sağlar.
Sıkça Sorulan Sorular
En uygun sayı, proje ve ekip büyüklüğüne bağlıdır. 5 kişilik bir ekip için 6–10 modül yeterlidir. 20'den fazla geliştirici için 20–40 modül. Kural: bir modül, bir geliştiricinin tamamen anlayabileceği kadar küçük ve aşırı bağımlılık ağı oluşturmayacak kadar büyük olmalıdır.
Doğru modülerlik, paralel derleme ve önbellekleme sayesinde derlemeyi hızlandırır. Ancak sıkı bağımlılıklara sahip aşırı sayıda modül derlemeyi yavaşlatır — Gradle ve Xcode grafiği çözmek için zaman harcar. Hızlı derlemelerin anahtarı, geçişli bağımlılıkları en aza indirmek ve döngüsüzlüğü korumaktır.
Evet, ancak aşamalı olarak. Çekirdek modülleri (ağ, veritabanı) ayırarak başlayın, ardından özellikleri tek tek ayırın. Eski monolitik kodun yanında yeni modüler kodu etkinleştirmek için özellik işaretleri kullanın. Büyük bir uygulamanın tam geçişi 3 ila 12 ay sürer.
Modüller tek bir uygulama içindeki derleme birimleridir. Mikro hizmetler, farklı sunucularda çalışan ayrı süreçlerdir. Modüller kodu böler, mikro hizmetler çalışma zamanını böler. Mobil geliştirmede, “mikro uygulamalar” terimi genellikle bir melez olarak kullanılır: bağımsız uygulamalar olarak çalışabilen özellik modülleri.
Her modülün bağımsız olarak çalışan kendi birim testleri vardır. Entegrasyon testleri, modüller arasındaki etkileşimi doğrular. UI testleri, sahte verilerle özellik modüllerini kapsar. Modüler mimari testi basitleştirir: başka bir modülün bağımlılığını taklit etmek, bir monolitin bir parçasını taklit etmekten daha kolaydır.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun