Builder — mobil geliştirmede builder modelinin temelleri

Yazar: IT Sectr Yayınlanma: 2026-02-17 Okuma süresi: 7 dk

Builder — karmaşık nesnelerin adım adım oluşturulmasını sağlayan bir yaratım modelidir. Bir düzine parametreye sahip kurucudan farklı olarak Builder, her biri bir alanı yapılandıran bir çağrı zinciri aracılığıyla bir nesneyi birleştirir. Model, özellikle çok sayıda isteğe bağlı parametreye sahip nesneler için kullanışlıdır: ağ istemci yapılandırması, veritabanı ayarları, uyarı ve navigasyon oluşturucuları. Daha fazla bilgi için Refactoring Guru: Builder adresini ziyaret edin.

Ana Noktalar

  • Builder — süreç ve sonucu ayırarak adım adım nesne oluşturma
  • Fluent interface — kolay yapılandırma için set()/with() çağrı zinciri
  • Değişmezlik — Builder, setter gerektirmeyen hazır bir nesne oluşturur
  • Geriye uyumluluk — Builder'a yeni alanlar istemcileri bozmadan eklenebilir
  • Kotlin DSL vs Builder — Kotlin alternatif olarak type-safe builders sunar

Builder Nedir: inşacı modelinin özü?

Builder — karmaşık bir nesnenin yapısını temsilinden ayıran bir GoF yaratım modelidir. Aynı yapım süreci farklı temsiller oluşturabilir. Builder, bir nesnenin çok sayıda isteğe bağlı parametresi olduğunda ve on alanlı bir kurucu okunamaz ve esnek olmadığında kullanışlıdır. Model ayrıca, kurucu aşırı yüklemelerinin sayısının katlanarak arttığı Telescoping Constructor anti-modelini de çözer.

Builder yapısı, ana sınıfın alanlarını yansıtan alanlara sahip bir iç statik Builder sınıfı içerir. Her set-yöntemi, akıcı zincirleme için Builder (this) döndürür. Son build() yöntemi, alan değerlerini özel bir kurucuya ileterek hedef nesneyi oluşturur. Ana sınıf, bir Builder kabul eden özel bir kurucuya sahiptir. İstemci: Object.builder().setField1(val1).setField2(val2).build().

Builder ne zaman kullanılır — yalnızca 2-3'ü zorunlu olan 5+ alana sahip nesneler. Yapılandırma nesneleri (RequestConfig, DatabaseConfig). Oluşturma sırasında karmaşık doğrulama mantığına sahip nesneler. Oluşturulduktan sonra değişmez (immutable) olması gereken nesneler. Android'de, Builder SDK'da aktif olarak kullanılır: AlertDialog.Builder, Retrofit.Builder, OkHttpClient.Builder, NotificationCompat.Builder.

Kotlin'de Builder: klasik ve DSL uygulaması

Kotlin'de Builder iki yaklaşıma sahiptir: klasik Java tarzı Builder (iç içe sınıf aracılığıyla) ve Kotlin tarzı DSL builder (alıcılı lambda aracılığıyla). Java tarzı Builder, Android uyumluluğu ve Java koduyla kullanım için tercih edilir. DSL builder, Kotlin'in deyimsel yoludur: bir fonksiyon, içinde this'in alanların doğrudan atanabileceği Builder bağlamı olduğu bir lambda kabul eder.

kotlin
// Klasik Builder
data class HttpConfig private constructor(
    val baseUrl: String,
    val timeout: Long = 30_000,
    val retries: Int = 3,
    val headers: Map<String, String> = emptyMap()
) {
    class Builder {
        private var baseUrl: String = ""
        private var timeout: Long = 30_000
        private var retries: Int = 3
        private var headers: MutableMap<String, String> = mutableMapOf()

        fun baseUrl(url: String) = apply { this.baseUrl = url }
        fun timeout(ms: Long) = apply { this.timeout = ms }
        fun retries(n: Int) = apply { this.retries = n }
        fun header(key: String, value: String) = apply { headers[key] = value }

        fun build(): HttpConfig {
            require(baseUrl.isNotBlank()) { "baseUrl is required" }
            return HttpConfig(baseUrl, timeout, retries, headers)
        }
    }
}

// Kullanım
val config = HttpConfig.Builder()
    .baseUrl("https://api.example.com")
    .timeout(15_000)
    .header("Authorization", "Bearer token")
    .build()

Kotlin DSL builder — iç içe sınıf olmadan bir alternatif. Bir builder fonksiyonu, bir builder nesnesi bağlamında bir lambda kabul eder. Bu Kotlin için deyimseldir ve write-alanları gerektirmez. DSL builder'lar Ktor Client, kotlinx.serialization, Compose (Modifier) içinde aktif olarak kullanılır. DSL builder, Java ile uyumlu değildir ve Java API'sine sahip kütüphaneler için uygun değildir.

Swift'te Builder: result builders ve zincirler

Swift'te Builder — Swift'in yerleşik bir Builder modeli yoktur, ancak Self döndüren yöntemler aracılığıyla akıcı bir arayüz kolayca uygulanır. Her yöntem bir özelliği yapılandırır ve self döndürür. Kotlin'in aksine, Swift ayrı bir Builder sınıfı gerektirmez — montaj sırasında değişebilir ise nesnenin kendisini döndürebilirsiniz. Değişmez nesneler için, Kotlin'e benzer şekilde iç içe bir Builder sınıfı kullanılır.

swift
struct NetworkRequest {
    let url: String
    let method: HTTPMethod
    let headers: [String: String]
    let body: Data?
    let timeout: TimeInterval

    final class Builder {
        private var url: String = ""
        private var method: HTTPMethod = .get
        private var headers: [String: String] = [:]
        private var body: Data? = nil
        private var timeout: TimeInterval = 30

        func withURL(_: String) -> Self { /* self */ }
        func withMethod(_: HTTPMethod) -> Self { /* self */ }
        func withHeader(key: String, value: String) -> Self { /* self */ }
        func withBody(_: Data) -> Self { /* self */ }
        func withTimeout(_: TimeInterval) -> Self { /* self */ }

        func build() throws -> NetworkRequest {
            guard !url.isEmpty else { throw BuilderError.missingURL }
            return NetworkRequest(
                url: url, method: method, headers: headers,
                body: body, timeout: timeout
            )
        }
    }
}

Result Builders — Swift 5.4, @resultBuilder'ı tanıttı — bildirimsel yapı oluşturma için bir dil mekanizması. SwiftUI, AttributedString, SceneBuilder result builder'lar kullanır. Bu klasik Builder'a bir alternatiftir: set-yöntemleri zinciri yerine, result builder, derleyicinin bir dizi veya ağaç halinde birleştirdiği öğeleri içeren bir kod bloğu kullanır. SwiftUI'daki @ViewBuilder en ünlü örnektir: body içinde if, switch, ForEach yazabilirsiniz ve derleyici koşullardan bir View oluşturur.

Builder vs Telescoping Constructor: yaklaşım karşılaştırması

Telescoping Constructor — bir sınıfın farklı parametre kümelerine sahip birçok aşırı yüklenmiş kurucuya sahip olduğu bir anti-modeldir. Örneğin, üç kurucu: HttpConfig(url), HttpConfig(url, timeout), HttpConfig(url, timeout, retries). Parametreler arttıkça, kurucu sayısı katlanarak artar — n isteğe bağlı alan için n! kombinasyon gerekir. Builder, yalnızca gerekli alanları belirlemeye izin vererek bu sorunu çözer.

ÖzellikTelescoping ConstructorBuilderKotlin named args
Kod miktarıKatlanarak artışDoğrusal artışMinimum
OkunabilirlikDüşük (hangi parametre ne?)Yüksek (yöntem + ad)Yüksek (ad = değer)
DeğişmezlikDeğişmezDeğişmezDeğişmez
Java uyumluluğuTamTamYok (yalnızca Kotlin)
DoğrulamaHer kurucudabuild()'de — bir kezinit()'de

Kotlin named arguments + varsayılan değerler — saf Kotlin projelerinde Builder'a zarif bir alternatiftir. Kurucu parametrelerinin varsayılan değerleri vardır, istemci yalnızca ihtiyaç duyulanları iletir: HttpConfig(baseUrl = url, timeout = 15_000). Dezavantajı, derleme zamanında zorunlu alanları doğrulayamamasıdır. Builder, Builder kurucusu aracılığıyla zorunlu alanlar sağlar (baseUrl zorunludur). Java kütüphaneleri için, Builder fiili standart olmaya devam etmektedir.

Android SDK'da Builder: AlertDialog, Retrofit, OkHttp

Android SDK'da Builder — standart kütüphanedeki en yaygın modellerden biridir. AlertDialog.Builder: new AlertDialog.Builder(context).setTitle().setMessage().setPositiveButton().create(). Retrofit.Builder: new Retrofit.Builder().baseUrl().addConverterFactory().build(). OkHttpClient.Builder: new OkHttpClient.Builder().connectTimeout().addInterceptor().build(). NotificationCompat.Builder: setContentTitle().setContentText().setSmallIcon().build().

Google'ın Builder kullanmasının nedeni — geriye uyumluluk. Builder'a yeni bir yöntem eklemek mevcut kodu bozmaz. Google 20 parametreli bir kurucu kullansaydı, her yeni alan yeni bir aşırı yükleme gerektirirdi. Builder, yıllar boyunca breaking changes olmadan set-yöntemleri eklemeye izin verir. Örneğin, NotificationCompat.Builder, Android 11'de mevcut kodu etkilemeden setBubbleMetadata() ekledi.

Kotlin kütüphanelerinde Builder — Ktor (HttpClientBuilder), Coil (ImageRequest.Builder), Room (Room.databaseBuilder(context, AppDatabase.class, "db").fallbackToDestructiveMigration().build()), Navigation (NavOptionsBuilder). Kotlin projelerinde, Builder genellikle DSL ile birleştirilir: Room.databaseBuilder(context, AppDatabase.class, "db").fallbackToDestructiveMigration().build(). Model, geriye uyumluluk ve Java birlikte çalışabilirliğinin önemli olduğu genel API'ler için geçerliliğini korumaktadır.

Sıkça Sorulan Sorular

Builder ne zaman gereksizdir?

Builder, 1-3 alanlı nesneler için gereksizdir — normal bir kurucu veya data class daha açıktır. Java birlikte çalışabilirliği olmayan Kotlin projelerinde de gereksizdir, burada named arguments + varsayılan değerler aynı görevi daha basit bir şekilde çözer. Builder, 5+ alan, karmaşık doğrulama veya named arguments'in bulunmadığı Java API'leri için haklıdır.

Builder, Factory'den nasıl farklıdır?

Builder karmaşık bir nesneyi adım adım oluşturur (alan yapılandırması), Factory bir nesneyi türüne veya parametrelerine göre tamamen oluşturur. Builder «nasıl birleştirilir?» sorusuna, Factory «ne oluşturulur?» sorusuna yanıt verir. Builder genellikle Factory ile birleştirilir: Factory türü seçer, Builder alanları yapılandırır.

SwiftUI'de Builder gerekli midir?

SwiftUI'de, Builder'ın rolünü result builders (@ViewBuilder, @SceneBuilder) ve View değiştiricileri (.font(), .padding()) üstlenir. SwiftUI bildirimsel bir yaklaşım ve akıcı değiştiriciler kullandığından klasik Builder gerekli değildir. UIKit bileşenleri için Builder kullanışlıdır: UIAlertController, URLRequest, NSAttributedString.

Builder nasıl thread-safe yapılır?

Builder normalde bir nesneyi birleştirmek için tek bir iş parçacığında kullanıldığından iş parçacığı güvenliği gerektirmez. Builder çoklu iş parçacığı ortamında (nadir durum) kullanılıyorsa, her set-yöntemini ve build()'i senkronize edin. Alternatif — Immutable Builder: her set-yöntemi, değiştirilmiş alanla yeni bir Builder örneği döndürür.

Retrofit neden DI yerine Builder kullanır?

Retrofit.Builder, bir DI kabı olmadan çalışması gereken genel bir kütüphane API'sidir. Builder, Dagger veya diğer DI çerçevelerine bağımlılıklar olmadan yapılandırma esnekliği (baseUrl, dönüştürücüler, interceptors, özel çağrı bağdaştırıcıları) sağlar. Bir uygulama içinde, DI Builder aracılığıyla Retrofit'i bir kez oluşturabilir, ancak Builder'ın kendisi Retrofit'in genel API'sinin bir parçası olarak kalır.

Özet

  • Builder — akıcı arayüzle adım adım nesne oluşturma
  • Kotlin Builder — klasik (iç içe sınıf) ve DSL (alıcılı lambda)
  • Swift Builder — bildirimsel kod için iç içe sınıf veya @resultBuilder
  • Değişmezlik — Builder özel kurucu aracılığıyla değişmez nesneler oluşturur
  • Android SDK — AlertDialog, Retrofit, OkHttp, NotificationCompat — sektör standardı
  • Geriye uyumluluk — Builder'a alan eklemek mevcut kodu bozmaz
  • Kotlin alternatifi — named arguments + varsayılan değerler saf Kotlin projeleri için daha basit

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.

Projeyi tartış

Ayrıca okuyun