Builder Pattern — murakkab obyektni bosqichma-bosqich yaratish jarayonini uning yakuniy ko‘rinishidan ajratadigan creational design pattern. U ko‘p parametrli constructorlar, ixtiyoriy maydonlar, validatsiya va turli konfiguratsiyali obyektlarni aniqroq yaratish uchun ishlatiladi.
Builder ayniqsa obyekt yaratish jarayoni bir necha qadamdan iborat bo‘lsa yoki constructor juda ko‘p argument qabul qilsa foydali.
Muammo
Quyidagi constructorni tasavvur qilish mumkin:
Server(
host,
port,
use_tls,
timeout,
retries,
proxy,
headers,
compression,
)
Argumentlar soni oshgani sari:
- tartibni adashtirish;
- boolean qiymatlarning ma’nosini yo‘qotish;
- defaultlarni boshqarish;
- yangi parametr qo‘shish;
- validation
qiyinlashadi.
Builder bu konfiguratsiyani nomlangan qadamlar bilan ajratadi.
Asosiy ishtirokchilar
Builder Pattern odatda quyidagi qismlardan iborat:
- Product — yaratiladigan obyekt;
- Builder — yaratish qadamlarini belgilovchi interface yoki class;
- Concrete Builder — haqiqiy qurilish jarayonini bajaradi;
- Director — qadamlar ketma-ketligini boshqarishi mumkin;
- Client — builder orqali obyektni yaratadi.
Director majburiy emas. Fluent builderlarda client qadamlarni bevosita chaqiradi.
Fluent interface
Builder methodlari ko‘pincha self yoki builder obyektining o‘zini qaytaradi.
config = (
ServerBuilder()
.host("api.uzbekdevs.uz")
.port(443)
.enable_tls()
.timeout(10)
.build()
)
Bunday yozuv o‘qilishi oson va parametrlarning ma’nosi aniq.
Build method
build() yakuniy obyektni yaratadi.
Bu bosqichda:
- required maydonlar tekshiriladi;
- qiymatlar normalizatsiya qilinadi;
- conflictlar aniqlanadi;
- immutable product yaratiladi;
- defaultlar qo‘llanadi.
Noto‘g‘ri konfiguratsiya build() vaqtida aniq xato beradi.
Required va optional qiymatlar
Builder required qiymatlarni constructor orqali olishi yoki build() vaqtida tekshirishi mumkin.
Masalan:
builder = RequestBuilder(method="GET", url="/wiki")
Optional qiymatlar keyingi methodlar orqali beriladi:
builder.header("Accept", "application/json")
builder.timeout(5)
Required maydonlarni juda kech tekshirish runtime xatoni ko‘paytirishi mumkin.
Immutable obyekt
Builder mutable bo‘lishi, product esa immutable bo‘lishi mumkin.
Yaratish davomida fieldlar o‘zgaradi.
build()dan keyin product o‘zgarmaydi.
Bu:
- thread safety;
- hashability;
- predictability;
- validation kafolati
uchun qulay.
Bir builderdan bir nechta product
Builder holatini reset qilib yoki nusxalab bir nechta o‘xshash obyekt yaratish mumkin.
Masalan, umumiy HTTP konfiguratsiya:
base headers
base timeout
base proxy
ustiga turli endpointlar qo‘shiladi.
Builder state tasodifan keyingi productga o‘tib ketmasligi uchun reset qoidasi aniq bo‘lishi kerak.
Director
Director ma’lum product variantini yaratish qadamlarini belgilaydi.
Masalan:
production server
development server
test server
Har variant bir xil builder interface’dan foydalanadi.
Director domain recipe’larni markazlashtiradi.
Builder va telescoping constructor
Telescoping constructor bir nechta overload yoki default constructorlar zanjiridan iborat.
Masalan:
User(name)
User(name, email)
User(name, email, role)
User(name, email, role, active)
Variantlar ko‘paygani sari boshqarish qiyinlashadi.
Builder bitta aniq yaratish interface beradi.
Builder va Factory
Factory odatda obyektni bir chaqiriqda yaratadi.
Builder esa obyektni bir necha qadamda yig‘adi.
create_database("postgres")
DatabaseBuilder
→ host
→ port
→ credentials
→ pool
→ build
Ikkalasi birga ham ishlatilishi mumkin.
Builder va Abstract Factory
Abstract Factory bog‘liq obyektlar oilasini yaratadi.
Builder bitta murakkab obyektni bosqichma-bosqich yaratadi.
Masalan, UI family uchun Abstract Factory, murakkab dialog konfiguratsiyasi uchun Builder ishlatilishi mumkin.
Validation
Builder domain invariantlarni bitta joyda tekshiradi.
Misollar:
- TLS yoqilgan bo‘lsa certificate kerak;
- port 1–65535 oralig‘ida;
- timeout musbat;
- ikki conflictli option birga ishlamaydi;
- required field mavjud.
Validation product constructoriga ham joylashtirilishi mumkin.
Serialization builder
Builder config yoki document yaratishda ham ishlatiladi.
Masalan:
Ammo methodlar faqat string concatenation qilsa injection va escaping muammosi yuzaga kelishi mumkin.
Query builder
SQL query builder column, filter, join va order qadamlarini birlashtiradi.
select
→ from
→ where
→ order
→ limit
Parameter qiymatlari bind parameter orqali berilishi kerak.
Builder xavfsizlikni avtomatik kafolatlamaydi.
Afzalliklari
Builder Pattern:
- o‘qilishi aniq obyekt yaratish;
- optional parametrlarni boshqarish;
- constructor murakkabligini kamaytirish;
- immutable product yaratish;
- validationni markazlashtirish;
- turli variantlarni bir xil qadamlar bilan yaratish
imkonini beradi.
Kamchiliklari
Builder qo‘shimcha class va kod yaratadi.
Oddiy obyekt uchun u ortiqcha bo‘lishi mumkin.
Product fieldlari o‘zgarsa builder ham yangilanadi.
Required qiymatlar compile-time darajada kafolatlanmasa xato build() vaqtida chiqadi.
Step Builder
Required qadamlar noto‘g‘ri tartibda chaqirilmasligi kerak bo‘lsa har qadam boshqa interface qaytaradigan Step Builder ishlatilishi mumkin.
Masalan:
host tanlash
→ port tanlash
→ security tanlash
→ build
Client host bermasdan build()ga o‘ta olmaydi.
Bu compile-time yordam beradi, ammo interface va generic type’lar sonini oshiradi.
Director’siz foydalanish
Ko‘p zamonaviy builderlarda Director alohida class sifatida mavjud emas.
Client fluent qadamlarni o‘zi chaqiradi.
Director faqat bir xil recipe ko‘p joyda takrorlansa foydali.
Masalan, UzbekDevs uchun test server konfiguratsiyasi bitta methodda saqlanib, barcha testlarda bir xil yaratilishi mumkin.
Thread safety
Builder odatda mutable bo‘lgani sabab bitta instance’ni bir nechta thread orasida bo‘lishish xavfli.
Har yaratish jarayoni uchun alohida builder ishlatiladi.
Product immutable bo‘lsa build qilingandan keyin xavfsizroq share qilinadi.
Bog‘liq tushunchalar
Creational pattern, Factory Method, Abstract Factory, Fluent interface, Immutable object, Director, Product, Object construction, Design pattern