Builder — основе градитељског обрасца у мобилном развоју

Аутор: IT Sectr Објављено: 2026-02-17 Време читања: 7 мин

Builder — стваралачки образац који омогућава креирање сложених објеката корак по корак. За разлику од конструктора са десет параметара, Builder саставља објекат кроз ланац позива, од којих сваки подешава једно поље. Образац је посебно користан за објекте са много опционих параметара: конфигурација мрежног клијента, подешавања базе података, градитељи алертова и навигације. Више на Refactoring Guru: Builder.

Главно

  • Builder — корачно конструисање објеката са раздвајањем процеса и резултата
  • Fluent interface — ланац позива set()/with() за згодно подешавање
  • Непроменљивост — Builder ствара готов објекат који не захтева сетере
  • Уназад компатибилност — нова поља се додају у Builder без ломљења клијената
  • Kotlin DSL vs Builder — Kotlin нуди type-safe builders као алтернативу

Шта је Builder: суштина градитељског обрасца?

Builder (градитељ) — стваралачки GoF образац који одваја конструисање сложеног објекта од његове репрезентације. Исти процес изградње може створити различите репрезентације. Builder је користан када објекат има много опционих параметара, а конструктор са десет поља је нечитак и нефлексибилан. Образац такође решава проблем Telescoping Constructor — антиобрасца где број преоптерећења конструктора расте експоненцијално.

Структура Builder укључује унутрашњу статичку класу Builder са пољима која копирају поља главне класе. Свака set-метода враћа Builder (this) за fluent chaining. Коначна build() метода ствара циљни објекат, прослеђујући вредности поља приватном конструктору. Главна класа има приватни конструктор који прима Builder. Клијент: Object.builder().setField1(val1).setField2(val2).build().

Када користити Builder — објекти са 5+ поља, од којих су само 2-3 обавезна. Конфигурациони објекти (RequestConfig, DatabaseConfig). Објекти са сложеном логиком валидације при креирању. Објекти који треба да буду непроменљиви (immutable) након креирања. У Android-у Builder се активно користи у SDK: AlertDialog.Builder, Retrofit.Builder, OkHttpClient.Builder, NotificationCompat.Builder.

Builder у Kotlin: класична и DSL имплементација

Kotlin Builder има два приступа: класични Java-style Builder (преко угњеждене класе) и Kotlin-style DSL builder (преко ламбде са ресивером). Java-style Builder је пожељан за компатибилност са Android-ом и при коришћењу са Java кодом. DSL builder — идиоматски Kotlin начин: функција прима ламбду, унутар које this представља Builder контекст, где се поља могу директно додељивати.

kotlin
// Класични 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)
        }
    }
}

// Коришћење
val config = HttpConfig.Builder()
    .baseUrl("https://api.example.com")
    .timeout(15_000)
    .header("Authorization", "Bearer token")
    .build()

Kotlin DSL builder — алтернатива без угњеждене класе. Функција-градитељ прима ламбду у контексту објекта-градитеља. Ово је идиоматски за Kotlin и не захтева write-поља. DSL builders се активно користе у Ktor Client, kotlinx.serialization, Compose (Modifier). DSL builder није компатибилан са Java и није погодан за библиотеке са Java API.

Builder у Swift: result builders и ланци

Swift Builder — Swift нема уграђени Builder образац, али fluent interface се лако имплементира кроз методе које враћају Self. Свака метода подешава својство и враћа self. За разлику од Kotlin-а, Swift не захтева посебну Builder класу — може се враћати сам објекат ако је mutable у фази склапања. За immutable објекте користи се угњеждена Builder класа по аналогији са Kotlin-ом.

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 — језички механизам за декларативно грађење структура. SwiftUI, AttributedString, SceneBuilder користе result builders. Ово је алтернатива класичном Builder-у: уместо ланца set-метода, result builder користи блок кода са елементима које компилатор сакупља у низ или стабло. @ViewBuilder у SwiftUI — најпознатији пример: унутар body-ја могу се писати if, switch, ForEach, а компилатор гради View из услова.

Builder vs Telescoping Constructor: поређење приступа

Telescoping Constructor — антиобразац где класа има више преоптерећених конструктора са различитим сетовима параметара. На пример, три конструктора: HttpConfig(url), HttpConfig(url, timeout), HttpConfig(url, timeout, retries). Са порастом параметара број конструктора расте експоненцијално — за n опционих поља потребно је n! комбинација. Builder решава овај проблем омогућавајући подешавање само потребних поља.

КарактеристикаTelescoping ConstructorBuilderKotlin named args
Количина кодаЕкспоненцијални растЛинеарни растМинимална
ЧитљивостНиска (који параметар?)Висока (метод + име)Висока (име = вредност)
НепроменљивостImmutableImmutableImmutable
Java компатибилностПотпунаПотпунаНе (само Kotlin)
ВалидацијаУ сваком конструкторуУ build() — једномУ init()

Kotlin named arguments + default values — елегантна алтернатива Builder-у у чистим Kotlin пројектима. Параметри конструктора имају подразумеване вредности, клијент прослеђује само потребне: HttpConfig(baseUrl = url, timeout = 15_000). Недостатак — немогућност валидације обавезних поља у фази компилације. Builder даје обавезна поља кроз Builder конструктор (baseUrl је обавезан). За Java библиотеке Builder остаје де факто стандард.

Builder у Android SDK: AlertDialog, Retrofit, OkHttp

Builder у Android SDK — један од најраспрострањенијих образаца у стандардној библиотеци. 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 користи Builder — уназад компатибилност. Додавање новог метода у Builder не ломи постојећи код. Да је Google користио конструктор са 20 параметара, свако ново поље би захтевало ново преоптерећење. Builder омогућава додавање set-метода годинама без breaking changes. На пример, NotificationCompat.Builder је додао setBubbleMetadata() у Android 11, не утичући на постојећи код.

Builder у Kotlin библиотекама — Ktor (HttpClientBuilder), Coil (ImageRequest.Builder), Room (Room.databaseBuilder()), Navigation (NavOptionsBuilder). У Kotlin пројектима Builder се често комбинује са DSL: Room.databaseBuilder(context, AppDatabase.class, "db").fallbackToDestructiveMigration().build(). Образац остаје актуелан за јавне API-је где су важни уназад компатибилност и Java интероп.

Често постављана питања

Када је Builder сувишан?

Builder је сувишан за објекте са 1-3 поља — обичан конструктор или data class су разумљивији. Такође је сувишан у Kotlin пројектима без Java интеропа, где named arguments + default values решавају исти задатак једноставније. Builder је оправдан за 5+ поља, сложену валидацију или Java API где named arguments нису доступни.

По чему се Builder разликује од Factory?

Builder ствара један сложен објекат корак по корак (подешавање поља), Factory ствара објекат у целини по типу или параметрима. Builder одговара на питање «како саставити?», Factory — «шта створити?». Builder се често комбинује са Factory: Factory бира тип, Builder подешава поља.

Да ли је Builder потребан у SwiftUI?

У SwiftUI улогу Builder-а обављају result builders (@ViewBuilder, @SceneBuilder) и модификатори View (.font(), .padding()). Класични Builder није потребан јер SwiftUI користи декларативни приступ и fluent modifiers. За UIKit компоненте Builder је користан: UIAlertController, URLRequest, NSAttributedString.

Како учинити Builder thread-safe?

Builder обично не захтева безбедност нити, јер се користи у једној нити за склапање објекта. Ако се Builder користи у вишенитном окружењу (редак случај), синхронизујте сваку set-методу и build(). Алтернатива — Immutable Builder: свака set-метода враћа нову инстанцу Builder-а са измењеним пољем.

Зашто Retrofit користи Builder, а не DI?

Retrofit.Builder — јавни API библиотеке који мора да ради без DI контејнера. Builder даје флексибилност подешавања (baseUrl, конвертори, интерцептори, прилагођени call adapterи) без зависности од Dagger-а или других DI. Унутар апликације DI може креирати Retrofit једном кроз Builder, али сам Builder остаје део јавног API-ја Retrofit-а.

Закључци

  • Builder — корачно конструисање објеката са fluent interface
  • Kotlin Builder — класични (угњеждена класа) и DSL (ламбда са ресивером)
  • Swift Builder — угњеждена класа или @resultBuilder за декларативни код
  • Непроменљивост — Builder ствара immutable објекте кроз приватни конструктор
  • Android SDK — AlertDialog, Retrofit, OkHttp, NotificationCompat — индустријски стандард
  • Уназад компатибилност — додавање поља у Builder не ломи постојећи код
  • Алтернатива Kotlin — named arguments + default values једноставнији за чисте Kotlin пројекте

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође