Advanced Topics pinned ยซ#mundarija # lar uchun Mundarija #sources Ma'lumotlar qayerdan olingani haqida.ยป
#introduction
Design Patternlar - biz ishlab chiqayotan dasturlarni loyihalashda ko'p uchraydigan muammolarni hal qilish uchun berilgan umumiy yechim hisoblanadi.
Biz patternlardan shunchaki nusxa olishimiz va dasturimizga qo'shish orqali muammoni hal qila olmaymiz. Aksincha Design Patternlar muammoga berilgan umumiy tushuncha bo'lganligi sababli biz ularni o'z dasturimizga moslashtirgan holda ish olib boramiz.
Nega ulardan foydalanishimiz kerak?
Design Patternlar - sinalgan va testlardan o'tgan yechimlar hisoblanadi. Ularni bilish orqali har qanday muammoga "Design principle" va "Object Oriented Design"lar orqali yech topa olishingiz mumkin.
Design Patternlar - siz va jamoadoshlaringiz birga ilshashlari uchun umumiy tilni belgilab beradi. Ya'ni sizga team-lead tomonidan "
Design Patternlar - biz ishlab chiqayotan dasturlarni loyihalashda ko'p uchraydigan muammolarni hal qilish uchun berilgan umumiy yechim hisoblanadi.
Biz patternlardan shunchaki nusxa olishimiz va dasturimizga qo'shish orqali muammoni hal qila olmaymiz. Aksincha Design Patternlar muammoga berilgan umumiy tushuncha bo'lganligi sababli biz ularni o'z dasturimizga moslashtirgan holda ish olib boramiz.
Nega ulardan foydalanishimiz kerak?
Design Patternlar - sinalgan va testlardan o'tgan yechimlar hisoblanadi. Ularni bilish orqali har qanday muammoga "Design principle" va "Object Oriented Design"lar orqali yech topa olishingiz mumkin.
Design Patternlar - siz va jamoadoshlaringiz birga ilshashlari uchun umumiy tilni belgilab beradi. Ya'ni sizga team-lead tomonidan "
Singleton Design Pattern" ni ishlatish haqida topshiriq keldi va siz ushbu pattenni bilganligingiz sababli ortiqcha tushintirishlarsiz ishni davom etasi.#type_of_patterns
Obyektning yaratilish jarayonida kodni qayta ishlatilinishi va yuqori darajadagi moslashuvchanlikni taminlab beradi.
Factory
Creational Design Patternlar
Obyektning yaratilish jarayonida kodni qayta ishlatilinishi va yuqori darajadagi moslashuvchanlikni taminlab beradi.
Factory
#factory
Ota klasslardagi (Superclass) obyektlarni yaratish uchun interface taminlaydi, ammo Bola klasslarda (Subclass) yaratilayotgan obyektlarning turini o'zgartirish imkonini beradi.
Tassavur qiling bizda quyidagi muammo mavjud:
Yuk tashuvchi Logistika kompaniyasi dasturining birinchi versiyasida faqatgina Quruqlik orqali yuk tashish hizmati mavjud. Demak bizda asosiy logika
Vaqt o'tishi bilan kompaniya kengayadi va suv transportiga talablar ortishi natijasida ular dasturga suv transporti uchun ishlaydigan funksiya qo'shishlariga to'g'ri keladi.
Bizda deyarli hamma jarayonlar quruqlik transporti bilan bir hil. Agarda suv transport uchun ham shu logikani qayta yozib chiqsak bu juda ham ko'p vaqt oladi, aksiga olib biz logikani
Ya'ni muammo har gal yangi turdagi transport turi qo'shilganda boshidan bir hil logika qayta va qayta yozishga to'g'ri keladi.
Biz Factory Design Pattern orqali muammoga yechim beramiz.
delivery() : transport turining logikasi yoziladi.
support() : ushbu klass qaysi turdagi transportlarga hizmat ko'rsatishini aniqlab beradi.
RoadLogistics va SeaLogistics klasslari Logistics dan vorislik oladi.
Product classiga esa type nomli field qo'shamiz.
Bizga kirib kelgan product typega asoslanib roadlogistics yoki sealogistics klasslaridan obyekt qaytaramiz. Va qaytagn obyektning delivery() funksiyasiga murojat qilamiz.
Agarda bizga havo transporti ham qo'shiladigan bo'lsa, biz
AirLogistics nomli klassga Logistics classdan vorislik olishimiz va Product ga AIR type qo'shishimiz orqali strukturani osongina AirLogistics klasga ko'chirib olamiz.
delivery() bu funksiyada esa har bir klassning o'zini logikasini yozamiz.
Factory Design Pattern
Ota klasslardagi (Superclass) obyektlarni yaratish uchun interface taminlaydi, ammo Bola klasslarda (Subclass) yaratilayotgan obyektlarning turini o'zgartirish imkonini beradi.
Tassavur qiling bizda quyidagi muammo mavjud:
Yuk tashuvchi Logistika kompaniyasi dasturining birinchi versiyasida faqatgina Quruqlik orqali yuk tashish hizmati mavjud. Demak bizda asosiy logika
Track klasida amalga oshadi. Vaqt o'tishi bilan kompaniya kengayadi va suv transportiga talablar ortishi natijasida ular dasturga suv transporti uchun ishlaydigan funksiya qo'shishlariga to'g'ri keladi.
Bizda deyarli hamma jarayonlar quruqlik transporti bilan bir hil. Agarda suv transport uchun ham shu logikani qayta yozib chiqsak bu juda ham ko'p vaqt oladi, aksiga olib biz logikani
Track klasiga bog'lab ketganmiz.Ya'ni muammo har gal yangi turdagi transport turi qo'shilganda boshidan bir hil logika qayta va qayta yozishga to'g'ri keladi.
Yechim
Biz Factory Design Pattern orqali muammoga yechim beramiz.
Logistics nomli parentclass boladi va uning quyidagi methodlari mavjud.
delivery() : transport turining logikasi yoziladi.
support() : ushbu klass qaysi turdagi transportlarga hizmat ko'rsatishini aniqlab beradi.
RoadLogistics va SeaLogistics klasslari Logistics dan vorislik oladi.
Product classiga esa type nomli field qo'shamiz.
Bizga kirib kelgan product typega asoslanib roadlogistics yoki sealogistics klasslaridan obyekt qaytaramiz. Va qaytagn obyektning delivery() funksiyasiga murojat qilamiz.
Agarda bizga havo transporti ham qo'shiladigan bo'lsa, biz
AirLogistics nomli klassga Logistics classdan vorislik olishimiz va Product ga AIR type qo'shishimiz orqali strukturani osongina AirLogistics klasga ko'chirib olamiz.
delivery() bu funksiyada esa har bir klassning o'zini logikasini yozamiz.
#singleton
Singleton Design Pattern - Creational Design Patterga mansub bo'lib biz yaratayotgan klassda faqatgina bitta obyekt bo'lishini taminlab beradi. Ya'ni necha marotaba klassdan obyekt olinishidan qatiy nazar klassda bitta obyekt bo'ladi va klass ichidagi resurslar faqatgina bitta obyekt tomonidan o'zgartib boriladi.
Singleton klass uchun meta klass yaratib olamiz.
Singleton klassda dict_ field mavjud bo'lib classdan necha marotaba obyekt olinishidan barcha obyektlar shu dict_ ustida ish olib boradi.
Natija ikkala klassda ham bir hil chiqadi.
Singleton Design Pattern - Creational Design Patterga mansub bo'lib biz yaratayotgan klassda faqatgina bitta obyekt bo'lishini taminlab beradi. Ya'ni necha marotaba klassdan obyekt olinishidan qatiy nazar klassda bitta obyekt bo'ladi va klass ichidagi resurslar faqatgina bitta obyekt tomonidan o'zgartib boriladi.
class SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
Singleton klass uchun meta klass yaratib olamiz.
_instances = {} klassdagi obyektlarni saqlash uchun ishlatilinadi.
agar klassdan obyekt olingan bo'lsa usha klass obyekti qaytarib yuboriladi aks holda esa _instances = {} klas set qilinadi.class Singleton(metaclass=SingletonMeta):
def __init__(self):
self.dict_ = {}
def set_value(self, key, value):
self.dict_[key] = value
def get_value(self):
return self.dict_
Singleton klassda dict_ field mavjud bo'lib classdan necha marotaba obyekt olinishidan barcha obyektlar shu dict_ ustida ish olib boradi.
if __name__ == '__main__':
singleton = Singleton()
singleton.set_value('key', 'value')
singleton2 = Singleton()
singleton2.set_value('key', 'value2')
print(singleton2.get_value())
print(singleton.get_value())
Natija ikkala klassda ham bir hil chiqadi.
#shared_state
Singleton Design Patternning o'ziga yarasha bir nechta kamchiliklari mavjud.
Umumiy olganda iloji boricha Singleton patternni ishlatishdan qochishimiz kerak. Agar shunday bo'lsa uning o'rniga nima ishlatishimiz mumkin?
Ayni shu paytda Shared State sahnaga chiqadi. Shared stateni Singleton patternga alternativ sifatida ishlatish mumkin. Ya'ni Shared Stateda global o'zgaruvchi (field) bo'ladi lekin bir nechta instancelar yaratilishi mumkin. Singletonda esa faqatgina bitta instance bo'ladi va har safar obyektlar invoke (chaqirilganda, instance olish jarayonida) osha yagona bo'lgan instance qaytariladi.
Shared Singletonga qaraganda kam hatoliklarga moyil, test qilish oson va oldingi klasslarni yaratish imkoni mavjud.
Singleton Design Patternning o'ziga yarasha bir nechta kamchiliklari mavjud.
1) OOP da barcha obyektlar bitta global varieable ni o'zgartirishi Best Practise emas.
2) Unit Test qilishda muammolar yuzaga kelishi, ya'ni test qilish jarayonida boshqa obyektlar tomonidan istalgan vaqtda field qiymatini o'zgartirilishi uning aniq qiymatini belgilashni qiyinlashtiradi (assertga aniq bir qiymat berish orqali tekshirish jarayonini).
Umumiy olganda iloji boricha Singleton patternni ishlatishdan qochishimiz kerak. Agar shunday bo'lsa uning o'rniga nima ishlatishimiz mumkin?
Ayni shu paytda Shared State sahnaga chiqadi. Shared stateni Singleton patternga alternativ sifatida ishlatish mumkin. Ya'ni Shared Stateda global o'zgaruvchi (field) bo'ladi lekin bir nechta instancelar yaratilishi mumkin. Singletonda esa faqatgina bitta instance bo'ladi va har safar obyektlar invoke (chaqirilganda, instance olish jarayonida) osha yagona bo'lgan instance qaytariladi.
Shared Singletonga qaraganda kam hatoliklarga moyil, test qilish oson va oldingi klasslarni yaratish imkoni mavjud.
#builder
Builder Design Pattern - murakkab obyektlarni osonlik bilan yaratish imkonini beradi. Ya'ni bizning ma'lum bir klasimizda ko'plab fieldlar bo'ladigan bo'lsa ularni hammasini bitta konstruktorga berib yuborish o'rniga navbatma-navbat kerakli fieldlarni qo'shish imkonini beradi.
Builder Design Patternni istalga dasturlash tiliga moslashtirib ishlatib ketish mumkin.
Javada build in @Builder anotatsiyasini klass ustiga qo'yish orqali bunga erishish mumkin.
Builder Design Pattern - murakkab obyektlarni osonlik bilan yaratish imkonini beradi. Ya'ni bizning ma'lum bir klasimizda ko'plab fieldlar bo'ladigan bo'lsa ularni hammasini bitta konstruktorga berib yuborish o'rniga navbatma-navbat kerakli fieldlarni qo'shish imkonini beradi.
Builder Design Patternni istalga dasturlash tiliga moslashtirib ishlatib ketish mumkin.
Javada build in @Builder anotatsiyasini klass ustiga qo'yish orqali bunga erishish mumkin.