Builder — एक सृजनात्मक पैटर्न जो जटिल वस्तुओं को चरण-दर-चरण बनाने की अनुमति देता है। दर्जनों पैरामीटर वाले कंस्ट्रक्टर के विपरीत, Builder कॉल की श्रृंखला के माध्यम से वस्तु को असेंबल करता है, प्रत्येक एक फ़ील्ड को कॉन्फ़िगर करता है। यह पैटर्न कई वैकल्पिक पैरामीटर वाली वस्तुओं के लिए विशेष रूप से उपयोगी है: नेटवर्क क्लाइंट कॉन्फ़िगरेशन, डेटाबेस सेटिंग्स, अलर्ट और नेविगेशन बिल्डर। अधिक जानकारी के लिए Refactoring Guru: Builder देखें।
मुख्य बिंदु
Builder — एक सृजनात्मक GoF पैटर्न जो जटिल वस्तु के निर्माण को उसके प्रतिनिधित्व से अलग करता है। वही निर्माण प्रक्रिया विभिन्न प्रतिनिधित्व बना सकती है। Builder तब उपयोगी होता है जब किसी वस्तु में कई वैकल्पिक पैरामीटर हों और दस फ़ील्ड वाला कंस्ट्रक्टर अपठनीय और अनम्य हो। यह पैटर्न Telescoping Constructor एंटी-पैटर्न को भी हल करता है, जहाँ कंस्ट्रक्टर ओवरलोड की संख्या तेज़ी से बढ़ती है।
Builder संरचना में मुख्य वर्ग के फ़ील्ड को दर्शाने वाले फ़ील्ड के साथ एक आंतरिक स्थैतिक Builder वर्ग शामिल है। प्रत्येक set-विधि fluent chaining के लिए Builder (this) लौटाती है। अंतिम 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.
Kotlin Builder के दो दृष्टिकोण हैं: क्लासिक Java-शैली Builder (नेस्टेड वर्ग के माध्यम से) और Kotlin-शैली DSL builder (रिसीवर के साथ लैम्ब्डा के माध्यम से)। Java-शैली Builder Android संगतता के लिए और Java कोड के साथ उपयोग करने पर बेहतर है। DSL builder Kotlin का स्वाभाविक तरीका है: एक फ़ंक्शन लैम्ब्डा स्वीकार करता है जिसके अंदर this Builder संदर्भ है जहाँ फ़ील्ड सीधे असाइन किए जा सकते हैं।
// क्लासिक 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 — नेस्टेड वर्ग के बिना एक विकल्प। एक builder फ़ंक्शन बिल्डर वस्तु के संदर्भ में लैम्ब्डा स्वीकार करता है। यह Kotlin के लिए स्वाभाविक है और write-फ़ील्ड की आवश्यकता नहीं होती। DSL builders का Ktor Client, kotlinx.serialization, Compose (Modifier) में सक्रिय रूप से उपयोग किया जाता है। DSL builder Java के साथ संगत नहीं है और Java API वाली लाइब्रेरी के लिए उपयुक्त नहीं है।
Swift Builder — Swift में अंतर्निहित Builder पैटर्न नहीं है, लेकिन Self लौटाने वाली विधियों के माध्यम से fluent interface आसानी से कार्यान्वित किया जाता है। प्रत्येक विधि एक गुण कॉन्फ़िगर करती है और self लौटाती है। Kotlin के विपरीत, Swift को अलग Builder वर्ग की आवश्यकता नहीं होती — यदि वस्तु असेंबली के दौरान mutable है तो आप स्वयं वस्तु लौटा सकते हैं। अपरिवर्तनीय वस्तुओं के लिए, Kotlin के समान एक नेस्टेड Builder वर्ग का उपयोग किया जाता है।
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 कोड ब्लॉक का उपयोग करता है जिसमें तत्व होते हैं जिन्हें कंपाइलर एक सरणी या पेड़ में इकट्ठा करता है। SwiftUI में @ViewBuilder सबसे प्रसिद्ध उदाहरण है: body के अंदर if, switch, ForEach लिखा जा सकता है, और कंपाइलर शर्तों से View बनाता है।
Telescoping Constructor — एक एंटी-पैटर्न जहाँ एक वर्ग में पैरामीटर के विभिन्न सेटों के साथ कई ओवरलोडेड कंस्ट्रक्टर होते हैं। उदाहरण के लिए, तीन कंस्ट्रक्टर: HttpConfig(url), HttpConfig(url, timeout), HttpConfig(url, timeout, retries)। पैरामीटर बढ़ने के साथ, कंस्ट्रक्टरों की संख्या तेज़ी से बढ़ती है — n वैकल्पिक फ़ील्ड के लिए n! संयोजन चाहिए। Builder केवल आवश्यक फ़ील्ड निर्दिष्ट करने की अनुमति देकर इस समस्या को हल करता है।
| विशेषता | Telescoping Constructor | Builder | Kotlin named args |
|---|---|---|---|
| कोड की मात्रा | तेज़ी से वृद्धि | रैखिक वृद्धि | न्यूनतम |
| पठनीयता | कम (कौन सा पैरामीटर क्या है?) | उच्च (विधि + नाम) | उच्च (नाम = मान) |
| अपरिवर्तनीयता | अपरिवर्तनीय | अपरिवर्तनीय | अपरिवर्तनीय |
| Java संगतता | पूर्ण | पूर्ण | कोई नहीं (केवल Kotlin) |
| सत्यापन | प्रत्येक कंस्ट्रक्टर में | build() में — एक बार | init() में |
Kotlin named arguments + डिफ़ॉल्ट मान — शुद्ध Kotlin प्रोजेक्ट में Builder का एक सुरुचिपूर्ण विकल्प। कंस्ट्रक्टर पैरामीटर के डिफ़ॉल्ट मान होते हैं, क्लाइंट केवल आवश्यक मान पास करता है: HttpConfig(baseUrl = url, timeout = 15_000)। कमी संकलन समय पर आवश्यक फ़ील्ड को सत्यापित करने में असमर्थता है। Builder Builder कंस्ट्रक्टर के माध्यम से आवश्यक फ़ील्ड प्रदान करता है (baseUrl आवश्यक है)। Java लाइब्रेरी के लिए, Builder वास्तविक मानक बना हुआ है।
Android SDK में Builder — मानक लाइब्रेरी में सबसे सामान्य पैटर्न में से एक। 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 वर्षों तक बिना breaking changes के set-विधियाँ जोड़ने की अनुमति देता है। उदाहरण के लिए, NotificationCompat.Builder ने Android 11 में setBubbleMetadata() जोड़ा, मौजूदा कोड को प्रभावित किए बिना।
Kotlin लाइब्रेरी में Builder — Ktor (HttpClientBuilder), Coil (ImageRequest.Builder), Room (Room.databaseBuilder(context, AppDatabase.class, "db").fallbackToDestructiveMigration().build()), Navigation (NavOptionsBuilder)। Kotlin प्रोजेक्ट में, Builder अक्सर DSL के साथ संयुक्त होता है: Room.databaseBuilder(context, AppDatabase.class, "db").fallbackToDestructiveMigration().build(). पैटर्न सार्वजनिक APIs के लिए प्रासंगिक बना हुआ है जहाँ पश्चगामी संगतता और Java इंटरऑप महत्वपूर्ण हैं।
अक्सर पूछे जाने वाले प्रश्न
Builder 1-3 फ़ील्ड वाली वस्तुओं के लिए अत्यधिक है — सामान्य कंस्ट्रक्टर या data class स्पष्ट है। यह Java इंटरऑप के बिना Kotlin प्रोजेक्ट में भी अत्यधिक है, जहाँ named arguments + डिफ़ॉल्ट मान उसी कार्य को अधिक सरलता से हल करते हैं। Builder 5+ फ़ील्ड, जटिल सत्यापन या Java APIs के लिए उचित है जहाँ named arguments उपलब्ध नहीं हैं।
Builder एक जटिल वस्तु चरण-दर-चरण बनाता है (फ़ील्ड कॉन्फ़िगरेशन), Factory प्रकार या पैरामीटर के अनुसार संपूर्ण वस्तु बनाता है। Builder प्रश्न «कैसे इकट्ठा करें?» का उत्तर देता है, Factory «क्या बनाएँ?» का। Builder अक्सर Factory के साथ संयुक्त होता है: Factory प्रकार चुनता है, Builder फ़ील्ड कॉन्फ़िगर करता है।
SwiftUI में, Builder की भूमिका result builders (@ViewBuilder, @SceneBuilder) और View संशोधक (.font(), .padding()) निभाते हैं। क्लासिक Builder की आवश्यकता नहीं है क्योंकि SwiftUI घोषणात्मक दृष्टिकोण और fluent modifiers का उपयोग करता है। UIKit घटकों के लिए, Builder उपयोगी है: UIAlertController, URLRequest, NSAttributedString।
Builder को आमतौर पर थ्रेड सुरक्षा की आवश्यकता नहीं होती क्योंकि इसका उपयोग एक वस्तु को इकट्ठा करने के लिए एक थ्रेड में किया जाता है। यदि Builder का उपयोग मल्टीथ्रेडेड वातावरण (दुर्लभ मामला) में किया जाता है, तो प्रत्येक set-विधि और build() को सिंक्रनाइज़ करें। विकल्प — Immutable Builder: प्रत्येक set-विधि संशोधित फ़ील्ड के साथ एक नया Builder उदाहरण लौटाती है।
Retrofit.Builder एक सार्वजनिक लाइब्रेरी API है जिसे DI कंटेनर के बिना काम करना चाहिए। Builder Dagger या अन्य DI ढाँचों पर निर्भरता के बिना कॉन्फ़िगरेशन लचीलापन (baseUrl, कनवर्टर, इंटरसेप्टर, कस्टम कॉल एडेप्टर) प्रदान करता है। एक ऐप्लिकेशन के अंदर, DI Builder के माध्यम से एक बार Retrofit बना सकता है, लेकिन Builder स्वयं Retrofit के सार्वजनिक API का हिस्सा बना रहता है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें