Skip to content

Modüler Mimari Yapıları

Modern enterprise mobil uygulamalarda modüler mimari, ölçeklenebilirlik, sürdürülebilirlik ve takım verimliliği açısından kritik öneme sahip bir mimari yaklaşımdır. Bu yaklaşım, büyük ölçekli uygulamaları yönetilebilir, bağımsız modüllere ayırarak paralel geliştirme, izole test etme ve aşamalı dağıtımı mümkün kılar.

Modüler Mimari İlkeleri

Modüler mimari temelde, endişelerin ayrılması ilkesine dayanan ve yüksek uyum, düşük bağlantı hedeflerini başaran bir sistem tasarım felsefesidir. Bu yaklaşım, karmaşık sistemleri iyi tanımlanmış sınırlara sahip daha küçük, odaklanmış bileşenlere ayırır.

Tek Sorumluluk Modülü Tasarımı

Her modül, tek sorumluluk ilkesini uygulayarak belirli alan işlevselliğini kapsüller. Bu tasarım felsefesi, modül karmaşıklığını yönetilebilir seviyelerde tutar ve değişim yayılımını minimize eder.

typescript
// Özellik modülü yapısı örneği
export interface UserFeatureModule {
    // Genel API yüzeyi
    getUserProfile(userId: string): Promise<UserProfile>;
    updateUserProfile(userId: string, profile: Partial<UserProfile>): Promise<void>;
    getUserPreferences(userId: string): Promise<UserPreferences>;
    
    // Modül yaşam döngüsü
    initialize(dependencies: UserModuleDependencies): void;
    dispose(): void;
}

// Dahili modül uygulaması
class UserFeatureModuleImpl implements UserFeatureModule {
    private userRepository: UserRepository;
    private cacheManager: CacheManager;
    private analyticsService: AnalyticsService;
    
    constructor(private dependencies: UserModuleDependencies) {
        this.userRepository = dependencies.userRepository;
        this.cacheManager = dependencies.cacheManager;
        this.analyticsService = dependencies.analyticsService;
    }
    
    async getUserProfile(userId: string): Promise<UserProfile> {
        // Önce önbellek stratejisi
        const cachedProfile = await this.cacheManager.get(`user_profile_${userId}`);
        if (cachedProfile) {
            this.analyticsService.track('user_profile_cache_hit');
            return cachedProfile;
        }
        
        // Depodan getir
        const profile = await this.userRepository.findById(userId);
        await this.cacheManager.set(`user_profile_${userId}`, profile, { ttl: 300 });
        
        this.analyticsService.track('user_profile_fetch');
        return profile;
    }
    
    initialize(dependencies: UserModuleDependencies): void {
        // Modül başlatma mantığı
        this.setupEventListeners();
        this.preloadCriticalData();
    }
    
    dispose(): void {
        // Kaynakları temizle
        this.cacheManager.clear();
        this.removeEventListeners();
    }
}

Bu uygulama, modülün dış bağımlılıklarını açıkça tanımlarken, iç uygulama detaylarını kapsüller.

Arayüz Tabanlı Modül İletişimi

Modüller arası iletişim, iyi tanımlanmış arayüzler aracılığıyla uygulanır. Bu yaklaşım, derleme zamanı sözleşme doğrulaması sağlarken, çalışma zamanı esnekliğini korur.

swift
// Swift'te protokol tabanlı modül arayüzü
protocol AuthenticationModule {
        func authenticateUser(credentials: UserCredentials) async throws -> AuthenticationResult
        func refreshToken(_ token: RefreshToken) async throws -> AccessToken
        func signOut() async throws
        
        var isAuthenticated: Bool { get }
        var currentUser: User? { get }
}

protocol NotificationModule {
        func scheduleNotification(_ notification: LocalNotification) async throws
        func cancelNotification(id: String) async throws
        func requestPermissions() async throws -> NotificationPermissionStatus
}

// Modüller arası iletişimi yöneten modül koordinatörü
class ModuleCoordinator {
        private let authModule: AuthenticationModule
        private let notificationModule: NotificationModule
        private let userModule: UserFeatureModule
        
        init(
                authModule: AuthenticationModule,
                notificationModule: NotificationModule,
                userModule: UserFeatureModule
        ) {
                self.authModule = authModule
                self.notificationModule = notificationModule
                self.userModule = userModule
                
                setupModuleInteractions()
        }
        
        private func setupModuleInteractions() {
                // Kimlik doğrulama durum değişiklikleri kullanıcı verisi güncellemelerini tetikler
                authModule.onAuthenticationStateChanged { [weak self] isAuthenticated in
                        if isAuthenticated {
                                self?.userModule.preloadUserData()
                                self?.notificationModule.enablePushNotifications()
                        } else {
                                self?.userModule.clearUserData()
                                self?.notificationModule.disablePushNotifications()
                        }
                }
        }
}

Özellik Tabanlı Modül Organizasyonu

Büyük ölçekli mobil uygulamalarda, özellik tabanlı modül organizasyon stratejisi, alan odaklı tasarım ilkelerini mobil mimariye uyarlar. Bu yaklaşım, iş yetenekleri etrafında modülleri organize ederek takım özerkliğini ve paralel geliştirmeyi kolaylaştırır.

Alan Odaklı Modül Sınırları

Alan sınırları, iş mantığı uyumuna dayanan doğal modül ayrım noktaları sağlar. Her alan modülü, belirli iş yeteneğini tamamen kapsüller ve minimum dış bağımlılık gerektirir.

kotlin
// Android'de özellik modülü yapısı
@Module
@InstallIn(SingletonComponent::class)
object EcommerceFeatureModule {
        
        @Provides
        @Singleton
        fun provideProductCatalogService(
                productRepository: ProductRepository,
                searchEngine: SearchEngine,
                recommendationEngine: RecommendationEngine
        ): ProductCatalogService {
                return ProductCatalogServiceImpl(
                        productRepository = productRepository,
                        searchEngine = searchEngine,
                        recommendationEngine = recommendationEngine
                )
        }
        
        @Provides
        @Singleton
        fun provideShoppingCartService(
                cartRepository: CartRepository,
                pricingEngine: PricingEngine,
                inventoryService: InventoryService
        ): ShoppingCartService {
                return ShoppingCartServiceImpl(
                        cartRepository = cartRepository,
                        pricingEngine = pricingEngine,
                        inventoryService = inventoryService
                )
        }
        
        @Provides
        @Singleton
        fun provideOrderManagementService(
                orderRepository: OrderRepository,
                paymentService: PaymentService,
                shippingService: ShippingService,
                notificationService: NotificationService
        ): OrderManagementService {
                return OrderManagementServiceImpl(
                        orderRepository = orderRepository,
                        paymentService = paymentService,
                        shippingService = shippingService,
                        notificationService = notificationService
                )
        }
}

// Özellik modülü genel API'si
interface EcommerceModule {
        val productCatalog: ProductCatalogService
        val shoppingCart: ShoppingCartService
        val orderManagement: OrderManagementService
}

Kapsamlı Endişelerin Yönetimi

Kapsamlı endişeler, birden fazla modüle yayılan işlevsellikler olup, özelleşmiş altyapı modülleri tarafından ele alınırlar. Günlükleme, güvenlik, önbellekleme gibi endişeler, özel modüller aracılığıyla merkezi yönetim alırlar.

typescript
// Kapsamlı endişeler için altyapı modülü
export class InfrastructureModule {
    private logger: Logger;
    private securityManager: SecurityManager;
    private cacheManager: CacheManager;
    private analyticsEngine: AnalyticsEngine;
    
    constructor(config: InfrastructureConfig) {
        this.logger = new StructuredLogger(config.logging);
        this.securityManager = new SecurityManager(config.security);
        this.cacheManager = new MultiLevelCacheManager(config.caching);
        this.analyticsEngine = new AnalyticsEngine(config.analytics);
    }
    
    // Kapsamlı endişeler için yön odaklı programlama
    createProxy<T>(target: T, moduleName: string): T {
        return new Proxy(target, {
            get: (target, property, receiver) => {
                const originalMethod = Reflect.get(target, property, receiver);
                
                if (typeof originalMethod === 'function') {
                    return (...args: any[]) => {
                        // Güvenlik kontrolü
                        this.securityManager.validateAccess(moduleName, property as string);
                        
                        // Günlükleme
                        this.logger.info(`${moduleName}.${property as string} çağrıldı`, { args });
                        
                        // Performans izleme
                        const startTime = performance.now();
                        
                        try {
                            const result = originalMethod.apply(target, args);
                            
                            // Asenkron metodları ele al
                            if (result instanceof Promise) {
                                return result
                                    .then(value => {
                                        this.logMethodCompletion(moduleName, property as string, startTime);
                                        return value;
                                    })
                                    .catch(error => {
                                        this.logMethodError(moduleName, property as string, startTime, error);
                                        throw error;
                                    });
                            }
                            
                            this.logMethodCompletion(moduleName, property as string, startTime);
                            return result;
                        } catch (error) {
                            this.logMethodError(moduleName, property as string, startTime, error);
                            throw error;
                        }
                    };
                }
                
                return originalMethod;
            }
        });
    }
}

Derleme Sistemi ve Modül Yönetimi

Modern mobil geliştirmede, gelişmiş derleme sistemleri modüler mimarinin etkili yönetimini sağlar. Bu sistemler, bağımlılık çözümlemesi, derleme optimizasyonu ve dağıtım stratejilerini ele alır.

Bağımlılık Grafiği Yönetimi

Modül bağımlılıkları, karmaşık yönlü asiklik grafikler (DAG) oluşturur ve derleme sisteminin verimli çözümleme ve doğrulamasını gerektirir. Döngüsel bağımlılıkların tespiti ve önlenmesi, sistem kararlılığı açısından kritik öneme sahiptir.

gradle
// Gradle çok modüllü derleme yapılandırması
plugins {
        id 'com.android.application'
        id 'kotlin-android'
        id 'kotlin-kapt'
        id 'dagger.hilt.android.plugin'
}

android {
        namespace 'com.enterprise.mobileapp'
        compileSdk 34
        
        defaultConfig {
                applicationId "com.enterprise.mobileapp"
                minSdk 24
                targetSdk 34
                versionCode 1
                versionName "1.0"
        }
        
        buildTypes {
                debug {
                        debuggable true
                        applicationIdSuffix ".debug"
                        buildConfigField "boolean", "ENABLE_LOGGING", "true"
                }
                release {
                        minifyEnabled true
                        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
                        buildConfigField "boolean", "ENABLE_LOGGING", "false"
                }
        }
}

dependencies {
        // Temel altyapı modülleri
        implementation project(':core:infrastructure')
        implementation project(':core:analytics')
        implementation project(':core:security')
        
        // Özellik modülleri
        implementation project(':features:authentication')
        implementation project(':features:user-profile')
        implementation project(':features:ecommerce')
        implementation project(':features:notifications')
        
        // Dış bağımlılıklar
        implementation libs.hilt.android
        kapt libs.hilt.compiler
        
        implementation libs.retrofit
        implementation libs.okhttp
        implementation libs.kotlinx.coroutines.android
}

Aşamalı Derleme Optimizasyonu

Modüler mimari, aşamalı derleme optimizasyonlarını sağlayarak geliştirme döngüsü sürelerini önemli ölçüde azaltır. Değişen modüllerin seçici derlemesi, büyük kod tabanlarında önemli zaman tasarrufu sağlar.

swift
// Swift Paket Yöneticisi modüler yapılandırması
// Package.swift
import PackageDescription

let package = Package(
        name: "MobileApp",
        platforms: [
                .iOS(.v15),
                .macOS(.v12)
        ],
        products: [
                .library(name: "CoreInfrastructure", targets: ["CoreInfrastructure"]),
                .library(name: "AuthenticationModule", targets: ["AuthenticationModule"]),
                .library(name: "UserProfileModule", targets: ["UserProfileModule"]),
                .library(name: "EcommerceModule", targets: ["EcommerceModule"])
        ],
        dependencies: [
                .package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.0.0"),
                .package(url: "https://github.com/realm/realm-swift.git", from: "10.0.0")
        ],
        targets: [
                // Temel altyapı
                .target(
                        name: "CoreInfrastructure",
                        dependencies: ["Alamofire"],
                        path: "Sources/CoreInfrastructure"
                ),
                
                // Özellik modülleri
                .target(
                        name: "AuthenticationModule",
                        dependencies: ["CoreInfrastructure"],
                        path: "Sources/Features/Authentication"
                ),
                
                .target(
                        name: "UserProfileModule",
                        dependencies: ["CoreInfrastructure", "AuthenticationModule"],
                        path: "Sources/Features/UserProfile"
                ),
                
                .target(
                        name: "EcommerceModule",
                        dependencies: [
                                "CoreInfrastructure", 
                                "AuthenticationModule", 
                                "UserProfileModule"
                        ],
                        path: "Sources/Features/Ecommerce"
                ),
                
                // Test hedefleri
                .testTarget(
                        name: "AuthenticationModuleTests",
                        dependencies: ["AuthenticationModule"],
                        path: "Tests/Features/Authentication"
                )
        ]
)

Dinamik Modül Yükleme

Gelişmiş mobil uygulamalarda, dinamik modül yükleme yetenekleri çalışma zamanı esnekliği sağlarken, uygulama başlatma performansını optimize eder. Bu teknik, isteğe bağlı özellik yükleme ve A/B test senaryolarında özellikle değerlidir.

Tembel Modül Başlatma

Tembel yükleme deseni, modüllerin ilk erişimde başlatılmasını sağlayarak uygulama başlatma süresini azaltır. Bu yaklaşım, bellek ayak izini optimize ederken, algılanan performansı artırır.

kotlin
// Android'de tembel modül yükleme
class ModuleRegistry {
        private val moduleFactories = mutableMapOf<String, () -> FeatureModule>()
        private val loadedModules = mutableMapOf<String, FeatureModule>()
        
        fun registerModule(name: String, factory: () -> FeatureModule) {
                moduleFactories[name] = factory
        }
        
        suspend fun loadModule(name: String): FeatureModule {
                return loadedModules[name] ?: run {
                        val module = withContext(Dispatchers.Default) {
                                moduleFactories[name]?.invoke()
                                        ?: throw IllegalArgumentException("$name modülü kayıtlı değil")
                        }
                        
                        module.initialize()
                        loadedModules[name] = module
                        
                        // Analitik takibi
                        analyticsService.track("module_loaded", mapOf(
                                "module_name" to name,
                                "load_time" to System.currentTimeMillis()
                        ))
                        
                        module
                }
        }
        
        suspend fun unloadModule(name: String) {
                loadedModules[name]?.let { module ->
                        module.dispose()
                        loadedModules.remove(name)
                        
                        // Modül için çöp toplamayı zorla
                        System.gc()
                        
                        analyticsService.track("module_unloaded", mapOf(
                                "module_name" to name
                        ))
                }
        }
}

Uzaktan Modül Teslimatı

Bulut tabanlı modül teslimatı, uygulamaların dağıtım sonrasında yeni özellikler almasını sağlar. Bu yaklaşım, uygulama mağazası onay döngülerini atlayarak, aşamalı kullanıma sunma stratejilerini mümkün kılar.

swift
// Uzaktan modül yükleme altyapısı
class RemoteModuleLoader {
        private let networkClient: NetworkClient
        private let moduleCache: ModuleCache
        private let securityValidator: ModuleSecurityValidator
        
        init(
                networkClient: NetworkClient,
                moduleCache: ModuleCache,
                securityValidator: ModuleSecurityValidator
        ) {
                self.networkClient = networkClient
                self.moduleCache = moduleCache
                self.securityValidator = securityValidator
        }
        
        func loadRemoteModule(moduleId: String, version: String) async throws -> FeatureModule {
                // Önce yerel önbelleği kontrol et
                if let cachedModule = await moduleCache.getModule(id: moduleId, version: version) {
                        return cachedModule
                }
                
                // Modül paketini indir
                let moduleBundle = try await networkClient.downloadModule(
                        id: moduleId,
                        version: version
                )
                
                // Güvenlik doğrulaması
                try securityValidator.validateModule(moduleBundle)
                
                // Modülü yükle ve örnekle
                let module = try await instantiateModule(from: moduleBundle)
                
                // Gelecekte kullanmak için önbelleğe al
                await moduleCache.storeModule(module, id: moduleId, version: version)
                
                return module
        }
        
        private func instantiateModule(from bundle: ModuleBundle) async throws -> FeatureModule {
                // Dinamik yükleme uygulaması
                guard let moduleClass = bundle.loadClass("FeatureModuleImpl") else {
                        throw ModuleLoadError.classNotFound
                }
                
                let module = try moduleClass.init() as! FeatureModule
                await module.initialize()
                
                return module
        }
}

Modüler Mimari için Test Stratejileri

Modüler mimari, kapsamlı test stratejilerinin uygulanmasını kolaylaştırır. Modül düzeyinde izolasyon, bağımsız testi mümkün kılarken, entegrasyon testleri karmaşık senaryoları doğrular.

Modül İzolasyon Testi

Her modül, izole edilmiş ortamda test edilebilir ve sahte bağımlılıklar kullanarak deterministik test senaryoları oluşturabilir. Bu yaklaşım, hızlı geri bildirim döngüleri ve güvenilir test yürütmesi sağlar.

typescript
// Modül izolasyon test çerçevesi
describe('UserProfileModule', () => {
    let userModule: UserFeatureModule;
    let mockDependencies: MockUserModuleDependencies;
    
    beforeEach(async () => {
        mockDependencies = createMockDependencies();
        userModule = new UserFeatureModuleImpl(mockDependencies);
        await userModule.initialize(mockDependencies);
    });
    
    afterEach(async () => {
        await userModule.dispose();
    });
    
    describe('getUserProfile', () => {
        it('kullanılabilir olduğunda önbelleğe alınmış profili döndürmeli', async () => {
            // Düzenle
            const userId = 'user-123';
            const cachedProfile = createMockUserProfile(userId);
            mockDependencies.cacheManager.get.mockResolvedValue(cachedProfile);
            
            // Uygula
            const result = await userModule.getUserProfile(userId);
            
            // Doğrula
            expect(result).toEqual(cachedProfile);
            expect(mockDependencies.cacheManager.get).toHaveBeenCalledWith(`user_profile_${userId}`);
            expect(mockDependencies.userRepository.findById).not.toHaveBeenCalled();
        });
        
        it('önbellek kaçırıldığında depodan almalı', async () => {
            // Düzenle
            const userId = 'user-456';
            const repositoryProfile = createMockUserProfile(userId);
            mockDependencies.cacheManager.get.mockResolvedValue(null);
            mockDependencies.userRepository.findById.mockResolvedValue(repositoryProfile);
            
            // Uygula
            const result = await userModule.getUserProfile(userId);
            
            // Doğrula
            expect(result).toEqual(repositoryProfile);
            expect(mockDependencies.userRepository.findById).toHaveBeenCalledWith(userId);
            expect(mockDependencies.cacheManager.set).toHaveBeenCalledWith(
                `user_profile_${userId}`,
                repositoryProfile,
                { ttl: 300 }
            );
        });
    });
});

Modüller Arası Entegrasyon Testi

Çapraz modül entegrasyon testi, modüllerin doğru işbirliğini doğrular ve sistem düzeyinde davranışı onaylar. Bu testler, uçtan uca senaryoları kapsarken, modül arayüz sözleşmelerini uygular.

kotlin
// Entegrasyon test çerçevesi
@RunWith(AndroidJUnit4::class)
@HiltAndroidTest
class ModuleIntegrationTest {
        
        @get:Rule
        var hiltRule = HiltAndroidRule(this)
        
        @Inject
        lateinit var authModule: AuthenticationModule
        
        @Inject
        lateinit var userModule: UserFeatureModule
        
        @Inject
        lateinit var notificationModule: NotificationModule
        
        @Before
        fun setup() {
                hiltRule.inject()
        }
        
        @Test
        fun userAuthenticationFlow_shouldTriggerCrossModuleInteractions() = runTest {
                // Düzenle
                val credentials = UserCredentials("test@example.com", "password123")
                
                // Uygula - Kullanıcı kimlik doğrulaması
                val authResult = authModule.authenticateUser(credentials)
                
                // Doğrula - Kimlik doğrulama başarılı
                assertTrue(authResult.isSuccess)
                assertTrue(authModule.isAuthenticated)
                
                // Doğrula - Kullanıcı modülü kimlik doğrulama olayını alır
                val currentUser = userModule.getCurrentUser()
                assertNotNull(currentUser)
                assertEquals(credentials.email, currentUser?.email)
                
                // Doğrula - Bildirim modülü etkinleştirilir
                val notificationStatus = notificationModule.getPermissionStatus()
                assertTrue(notificationStatus.isEnabled)
                
                // Uygula - Çıkış yap
                authModule.signOut()
                
                // Doğrula - Tüm modüller çıkışa tepki verir
                assertFalse(authModule.isAuthenticated)
                assertNull(userModule.getCurrentUser())
                assertFalse(notificationModule.getPermissionStatus().isEnabled)
        }
}

Modüler mimari deseninin kapsamlı uygulaması, büyük ölçekli mobil uygulamalarda sürdürülebilirlik, ölçeklenebilirlik ve takım verimliliğini dramatik olarak iyileştirir. Bu sistematik yaklaşım, karmaşık sistemlerin yönetilebilir bileşenlere ayrılmasını sağlarken, yüksek kaliteli yazılım teslimatını kolaylaştırır.

Eren Demir tarafından oluşturulmuştur.