Python yaratuvchan dizayn naqshlarini o'rganing: Singleton, Fabrika, Abstrak Fabrika, Builder va Prototip. Ularning amalga oshirilishi, afzalliklari va real-dunyodagi ilovalarini o'rganing.
Python dizayn naqshlari: Yaratuvchan naqshlarga chuqur kirish
Dizayn naqshlari - bu dasturiy ta'minot dizaynida tez-tez uchraydigan muammolarni qayta ishlatiladigan echimlardir. Ular ushbu muammolarni qanday hal qilish bo'yicha reja beradi, kodni qayta ishlatish, saqlash va moslashuvchanlikni rag'batlantiradi. Yaratuvchan dizayn naqshlari, xususan, ob'ektlarni yaratish mexanizmlari bilan shug'ullanadi, ob'ektlarni vaziyatga mos ravishda yaratishga harakat qiladi. Ushbu maqola Python-dagi yaratuvchan dizayn naqshlarini keng qamrovli o'rganishni ta'minlaydi, shu jumladan batafsil tushuntirishlar, kod misollari va global auditoriya uchun dolzarb bo'lgan amaliy ilovalar.
Yaratuvchan dizayn naqshlari nima?
Yaratuvchan dizayn naqshlari instantiatsiya jarayonini ajratib ko'rsatadi. Ular mijoz kodini instantiatsiya qilinayotgan maxsus sinflardan ajratib, ob'ektlarni yaratish ustidan katta moslashuvchanlik va nazoratni ta'minlaydi. Ushbu naqshlardan foydalanib, siz yaratiladigan ob'ektning aniq sinfini ko'rsatmasdan ob'ektlar yaratishingiz mumkin. Bu tashvishlarni ajratish kodni yanada mustahkam va saqlashni osonlashtiradi.
Yaratuvchan naqshlarning asosiy maqsadi - ob'ektni instantiatsiya qilish jarayonini ajratib ko'rsatish, ob'ekt yaratishning murakkabliklarini mijozdan yashirish. Bu dasturchilarga ob'ekt yaratishning mayda-chuydalariga botib ketmasdan, o'z ilovalarining yuqori darajadagi mantiqiga e'tibor qaratish imkonini beradi.
Yaratuvchan dizayn naqshlarining turlari
Ushbu maqolada quyidagi yaratuvchan dizayn naqshlarini ko'rib chiqamiz:
- Singleton: Sinfda faqat bitta misol bo'lishini ta'minlaydi va unga global kirish nuqtasini ta'minlaydi.
- Fabrika usuli: Ob'ekt yaratish uchun interfeysni belgilaydi, lekin quyi sinflarga qaysi sinfni instantiatsiya qilishni hal qilishga imkon beradi.
- Abstrak fabrika: O'zaro bog'liq yoki qaram ob'ektlar oilalarini ularning aniq sinflarini ko'rsatmasdan yaratish uchun interfeysni ta'minlaydi.
- Builder: Murakkab ob'ektni qurishni uning tasviridan ajratib turadi va bir xil qurilish jarayonining turli xil tasvirlarni yaratishiga imkon beradi.
- Prototip: Prototipik misoldan foydalanib yaratiladigan ob'ektlarning turini belgilaydi va ushbu prototipni nusxalash orqali yangi ob'ektlar yaratadi.
1. Singleton naqshi
Singleton naqshi sinfda faqat bitta misol bo'lishini ta'minlaydi va unga global kirish nuqtasini ta'minlaydi. Ushbu naqsh tizim bo'ylab harakatlarni muvofiqlashtirish uchun aniq bitta ob'ekt kerak bo'lganda foydalidir. U ko'pincha resurslarni boshqarish, jurnalga yozish yoki konfiguratsiya sozlamalari uchun ishlatiladi.
Amalga oshirish
Mana Singleton naqshining Python-dagi amalga oshirilishi:
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
# Misol uchun foydalanish
s1 = Singleton()
s2 = Singleton()
print(s1 is s2) # Natija: True
Tushuntirish:
_instance: Ushbu sinf o'zgaruvchisi sinfning yagona misolini saqlaydi.__new__: Ushbu usul ob'ekt yaratilganda__init__dan oldin chaqiriladi. U misol allaqachon mavjudligini tekshiradi. Agar yo'q bo'lsa, usuper().__new__(cls)yordamida yangi misolni yaratadi va uni_instanceda saqlaydi. Agar misol allaqachon mavjud bo'lsa, u mavjud misolni qaytaradi.
Foydalanish holatlari
- Ma'lumotlar bazasiga ulanish: Bir vaqtning o'zida ma'lumotlar bazasiga faqat bitta ulanish ochiq bo'lishini ta'minlash.
- Konfiguratsiya menejeri: Ilova konfiguratsiya sozlamalariga yagona kirish nuqtasini ta'minlash.
- Logger: Ilovadagi barcha jurnalga yozish operatsiyalarini bajarish uchun bitta jurnalga yozish misolini yaratish.
Misol
Singleton naqshidan foydalangan holda amalga oshirilgan konfiguratsiya menejerining oddiy misolini ko'rib chiqaylik:
class ConfigurationManager(Singleton):
def __init__(self):
if not hasattr(self, 'config'): # __init__ faqat bir marta chaqirilishini ta'minlash
self.config = {}
def set_config(self, key, value):
self.config[key] = value
def get_config(self, key):
return self.config.get(key)
# Misol uchun foydalanish
config_manager1 = ConfigurationManager()
config_manager1.set_config('database_url', 'localhost:5432')
config_manager2 = ConfigurationManager()
print(config_manager2.get_config('database_url')) # Natija: localhost:5432
2. Fabrika usuli naqshi
Fabrika usuli naqshi ob'ekt yaratish uchun interfeysni belgilaydi, lekin quyi sinflarga qaysi sinfni instantiatsiya qilishni hal qilishga imkon beradi. Fabrika usuli sinfga instantiatsiyani quyi sinflarga qoldirishga imkon beradi. Ushbu naqsh bo'sh bog'lanishni rag'batlantiradi va mavjud kodni o'zgartirmasdan yangi mahsulot turlarini qo'shishga imkon beradi.
Amalga oshirish
Mana Fabrika usuli naqshining Python-dagi amalga oshirilishi:
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Vov!";
class Cat(Animal):
def speak(self):
return "Miyov!";
class AnimalFactory(ABC):
@abstractmethod
def create_animal(self):
pass
class DogFactory(AnimalFactory):
def create_animal(self):
return Dog()
class CatFactory(AnimalFactory):
def create_animal(self):
return Cat()
# Mijoz kodi
def get_animal(factory: AnimalFactory):
animal = factory.create_animal()
return animal.speak()
dog_sound = get_animal(DogFactory())
cat_sound = get_animal(CatFactory())
print(f"It dedi: {dog_sound}") # Natija: It dedi: Vov!
print(f"Mushuk dedi: {cat_sound}") # Natija: Mushuk dedi: Miyov!
Tushuntirish:
Animal: Barcha hayvon turlari uchun interfeysni belgilovchi abstrak asos sinf.DogvaCat:Animalinterfeysini amalga oshiruvchi aniq sinflar.AnimalFactory: Hayvonlarni yaratish uchun interfeysni belgilovchi abstrak asos sinf.DogFactoryvaCatFactory:AnimalFactoryinterfeysini amalga oshiruvchi aniq sinflar, mos ravishdaDogvaCatmisollarini yaratish uchun javobgardir.get_animal: Fabrikadan hayvonni yaratish va ishlatish uchun foydalanadigan mijoz funktsiyasi.
Foydalanish holatlari
- UI Frameworklari: Turli operatsion tizimlar uchun turli fabrikalardan foydalanib, platformaga xos UI elementlarini (masalan, tugmalar, matn maydonlari) yaratish.
- O'yin ishlab chiqish: O'yin darajasi yoki foydalanuvchi tanloviga asoslangan holda turli xil o'yin qahramonlari yoki ob'ektlarini yaratish.
- Hujjatlarni qayta ishlash: Kerakli chiqish formatiga asoslangan holda turli fabrikalardan foydalanib, turli xil hujjatlarni (masalan, PDF, Word, HTML) yaratish.
Misol
Foydalanuvchi tanloviga asoslangan holda turli xil to'lov usullarini yaratmoqchi bo'lgan ssenariyni ko'rib chiqing. Buni Fabrika usuli naqshidan foydalanib qanday amalga oshirishingiz mumkin:
from abc import ABC, abstractmethod
class Payment(ABC):
@abstractmethod
def process_payment(self, amount):
pass
class CreditCardPayment(Payment):
def process_payment(self, amount):
return f"${amount} miqdoridagi kredit karta to'lovini qayta ishlash"
class PayPalPayment(Payment):
def process_payment(self, amount):
return f"${amount} miqdoridagi PayPal to'lovini qayta ishlash"
class PaymentFactory(ABC):
@abstractmethod
def create_payment_method(self):
pass
class CreditCardPaymentFactory(PaymentFactory):
def create_payment_method(self):
return CreditCardPayment()
class PayPalPaymentFactory(PaymentFactory):
def create_payment_method(self):
return PayPalPayment()
# Mijoz kodi
def process_payment(factory: PaymentFactory, amount):
payment_method = factory.create_payment_method()
return payment_method.process_payment(amount)
credit_card_payment = process_payment(CreditCardPaymentFactory(), 100)
paypal_payment = process_payment(PayPalPaymentFactory(), 50)
print(credit_card_payment) # Natija: $100 miqdoridagi kredit karta to'lovini qayta ishlash
print(paypal_payment) # Natija: $50 miqdoridagi PayPal to'lovini qayta ishlash
3. Abstrak fabrika naqshi
Abstrak fabrika naqshi o'zaro bog'liq yoki qaram ob'ektlar oilalarini ularning aniq sinflarini ko'rsatmasdan yaratish uchun interfeysni ta'minlaydi. Bu birgalikda ishlashga mo'ljallangan, mustahkamlik va moslikni ta'minlovchi ob'ektlarni yaratishga imkon beradi.
Amalga oshirish
Mana Abstrak fabrika naqshining Python-dagi amalga oshirilishi:
from abc import ABC, abstractmethod
class Button(ABC):
@abstractmethod
def paint(self):
pass
class Checkbox(ABC):
@abstractmethod
def paint(self):
pass
class GUIFactory(ABC):
@abstractmethod
def create_button(self):
pass
@abstractmethod
def create_checkbox(self):
pass
class WinFactory(GUIFactory):
def create_button(self):
return WinButton()
def create_checkbox(self):
return WinCheckbox()
class MacFactory(GUIFactory):
def create_button(self):
return MacButton()
def create_checkbox(self):
return MacCheckbox()
class WinButton(Button):
def paint(self):
return "Windows tugmasini ko'rsatish"
class MacButton(Button):
def paint(self):
return "Mac tugmasini ko'rsatish"
class WinCheckbox(Checkbox):
def paint(self):
return "Windows katakchasini ko'rsatish"
class MacCheckbox(Checkbox):
def paint(self):
return "Mac katakchasini ko'rsatish"
# Mijoz kodi
def paint_ui(factory: GUIFactory):
button = factory.create_button()
checkbox = factory.create_checkbox()
return button.paint(), checkbox.paint()
win_button, win_checkbox = paint_ui(WinFactory())
mac_button, mac_checkbox = paint_ui(MacFactory())
print(win_button) # Natija: Windows tugmasini ko'rsatish
print(win_checkbox) # Natija: Windows katakchasini ko'rsatish
print(mac_button) # Natija: Mac tugmasini ko'rsatish
print(mac_checkbox) # Natija: Mac katakchasini ko'rsatish
Tushuntirish:
ButtonvaCheckbox: UI elementlari uchun interfeyslarni belgilovchi abstrak asos sinflar.WinButton,MacButton,WinCheckboxvaMacCheckbox: Windows va Mac platformalari uchun UI elementi interfeyslarini amalga oshiruvchi aniq sinflar.GUIFactory: UI elementlari oilalarini yaratish uchun interfeysni belgilovchi abstrak asos sinf.WinFactoryvaMacFactory:GUIFactoryinterfeysini amalga oshiruvchi aniq sinflar, mos ravishda Windows va Mac platformalari uchun UI elementlarini yaratish uchun javobgardir.paint_ui: Fabrikadan UI elementlarini yaratish va ko'rsatish uchun foydalanadigan mijoz funktsiyasi.
Foydalanish holatlari
- UI Frameworklari: Muayyan operatsion tizim yoki platformaning ko'rinishi va hissi bilan mos keladigan UI elementlarini yaratish.
- O'yin ishlab chiqish: Muayyan o'yin darajasi yoki mavzusining uslubi bilan mos keladigan o'yin ob'ektlarini yaratish.
- Ma'lumotlarga kirish: Muayyan ma'lumotlar bazasi yoki ma'lumotlar manbai bilan mos keladigan ma'lumotlarga kirish ob'ektlarini yaratish.
Misol
Turli xil uslubdagi (masalan, zamonaviy, Viktoriya) turli xil mebellarni (masalan, stullar, stollar) yaratmoqchi bo'lgan ssenariyni ko'rib chiqing. Buni Abstrak fabrika naqshidan foydalanib qanday amalga oshirishingiz mumkin:
from abc import ABC, abstractmethod
class Chair(ABC):
@abstractmethod
def create(self):
pass
class Table(ABC):
@abstractmethod
def create(self):
pass
class FurnitureFactory(ABC):
@abstractmethod
def create_chair(self):
pass
@abstractmethod
def create_table(self):
pass
class ModernFurnitureFactory(FurnitureFactory):
def create_chair(self):
return ModernChair()
def create_table(self):
return ModernTable()
class VictorianFurnitureFactory(FurnitureFactory):
def create_chair(self):
return VictorianChair()
def create_table(self):
return VictorianTable()
class ModernChair(Chair):
def create(self):
return "Zamonaviy stulni yaratish"
class VictorianChair(Chair):
def create(self):
return "Viktoriya stulini yaratish"
class ModernTable(Table):
def create(self):
return "Zamonaviy stolni yaratish"
class VictorianTable(Table):
def create(self):
return "Viktoriya stolni yaratish"
# Mijoz kodi
def create_furniture(factory: FurnitureFactory):
chair = factory.create_chair()
table = factory.create_table()
return chair.create(), table.create()
modern_chair, modern_table = create_furniture(ModernFurnitureFactory())
victorian_chair, victorian_table = create_furniture(VictorianFurnitureFactory())
print(modern_chair) # Natija: Zamonaviy stulni yaratish
print(modern_table) # Natija: Zamonaviy stolni yaratish
print(victorian_chair) # Natija: Viktoriya stulini yaratish
print(victorian_table) # Natija: Viktoriya stolni yaratish
4. Builder naqshi
Builder naqshi murakkab ob'ektni qurishni uning tasviridan ajratib turadi va bir xil qurilish jarayonining turli xil tasvirlarni yaratishiga imkon beradi. Bu bir nechta ixtiyoriy komponentlarga ega murakkab ob'ektlarni yaratish kerak bo'lganda va ko'p sonli konstruktorlar yoki konfiguratsiya parametrlarini yaratmaslikni istaganingizda foydalidir.
Amalga oshirish
Mana Builder naqshining Python-dagi amalga oshirilishi:
class Pizza:
def __init__(self):
self.dough = None
self.sauce = None
self.topping = None
def __str__(self):
return f"Pizza xamiri: {self.dough}, sousi: {self.sauce} va to'ldirgichi: {self.topping}"
class PizzaBuilder:
def __init__(self):
self.pizza = Pizza()
def set_dough(self, dough):
self.pizza.dough = dough
return self
def set_sauce(self, sauce):
self.pizza.sauce = sauce
return self
def set_topping(self, topping):
self.pizza.topping = topping
return self
def build(self):
return self.pizza
# Mijoz kodi
pizza_builder = PizzaBuilder()
pizza = pizza_builder.set_dough("Yupqa qatlam").set_sauce("Pomidor").set_topping("Pepperoni").build()
print(pizza) # Natija: Pizza xamiri: Yupqa qatlam, sousi: Pomidor va to'ldirgichi: Pepperoni
Tushuntirish:
Pizza: Qurilishi kerak bo'lgan murakkab ob'ektni ifodalovchi sinf.PizzaBuilder:Pizzaob'ektining turli xil komponentlarini o'rnatish uchun usullarni taqdim etuvchi builder sinf.
Foydalanish holatlari
- Hujjatlarni yaratish: Turli xil bo'limlar va formatlash variantlariga ega murakkab hujjatlarni (masalan, hisobotlar, hisob-fakturalar) yaratish.
- O'yin ishlab chiqish: Turli xil atributlar va komponentlarga ega murakkab o'yin ob'ektlarini (masalan, qahramonlar, darajalar) yaratish.
- Ma'lumotlarni qayta ishlash: Turli xil tugunlar va munosabatlarga ega murakkab ma'lumotlar tuzilmalarini (masalan, graflar, daraxtlar) yaratish.
Misol
Turli xil komponentlarga (masalan, protsessor, RAM, xotira) ega turli xil kompyuterlarni qurmoqchi bo'lgan ssenariyni ko'rib chiqing. Buni Builder naqshidan foydalanib qanday amalga oshirishingiz mumkin:
class Computer:
def __init__(self):
self.cpu = None
self.ram = None
self.storage = None
self.graphics_card = None
def __str__(self):
return f"Kompyuter protsessori: {self.cpu}, RAM: {self.ram}, Xotira: {self.storage}, Grafik karta: {self.graphics_card}"
class ComputerBuilder:
def __init__(self):
self.computer = Computer()
def set_cpu(self, cpu):
self.computer.cpu = cpu
return self
def set_ram(self, ram):
self.computer.ram = ram
return self
def set_storage(self, storage):
self.computer.storage = storage
return self
def set_graphics_card(self, graphics_card):
self.computer.graphics_card = graphics_card
return self
def build(self):
return self.computer
# Mijoz kodi
computer_builder = ComputerBuilder()
computer = computer_builder.set_cpu("Intel i7").set_ram("16GB").set_storage("1TB SSD").set_graphics_card("Nvidia RTX 3080").build()
print(computer)
# Natija: Kompyuter protsessori: Intel i7, RAM: 16GB, Xotira: 1TB SSD, Grafik karta: Nvidia RTX 3080
5. Prototip naqshi
Prototip naqshi prototipik misoldan foydalanib yaratiladigan ob'ektlarning turini belgilaydi va ushbu prototipni nusxalash orqali yangi ob'ektlar yaratadi. Bu mavjud ob'ektni klonlash orqali yangi ob'ektlar yaratishga imkon beradi, ob'ektlarni noldan yaratish zaruratidan qochadi. Bu ob'ektlarni yaratish qimmat yoki murakkab bo'lganda foydali bo'lishi mumkin.
Amalga oshirish
Mana Prototip naqshining Python-dagi amalga oshirilishi:
import copy
class Prototype:
def __init__(self):
self._objects = {}
def register_object(self, name, obj):
self._objects[name] = obj
def unregister_object(self, name):
del self._objects[name]
def clone(self, name, **attrs):
obj = copy.deepcopy(self._objects.get(name))
if attrs:
obj.__dict__.update(attrs)
return obj
class Car:
def __init__(self):
self.name = ""
self.color = ""
self.options = []
def __str__(self):
return f"Mashina: Nomi={self.name}, Rangi={self.color}, Variantlar={self.options}"
# Mijoz kodi
prototype = Prototype()
car = Car()
car.name = "Umumiy mashina"
car.color = "Oq"
car.options = ["AC", "GPS"]
prototype.register_object("generic", car)
car1 = prototype.clone("generic", name="Sport mashinasi", color="Qizil", options=["AC", "GPS", "Spoiler"])
car2 = prototype.clone("generic", name="Oila mashinasi", color="Moviy", options=["AC", "GPS", "Sunroof"])
print(car1)
# Natija: Mashina: Nomi=Sport mashinasi, Rangi=Qizil, Variantlar=['AC', 'GPS', 'Spoiler']
print(car2)
# Natija: Mashina: Nomi=Oila mashinasi, Rangi=Moviy, Variantlar=['AC', 'GPS', 'Sunroof']
Tushuntirish:
Prototype: Prototipni boshqaradigan va ularni klonlash usulini taqdim etuvchi sinf.Car: Klonlanishi kerak bo'lgan ob'ektni ifodalovchi sinf.
Foydalanish holatlari
- O'yin ishlab chiqish: Bir-biriga o'xshash o'yin ob'ektlarini, masalan, dushmanlar yoki kuchaytirishlar yaratish.
- Hujjatlarni qayta ishlash: Shablonda asoslangan hujjatlarni yaratish.
- Konfiguratsiyani boshqarish: Standart konfiguratsiyada asoslangan konfiguratsiya ob'ektlarini yaratish.
Misol
Turli xil atributlarga (masalan, ismi, roli, bo'limi) ega turli xil xodimlarni yaratmoqchi bo'lgan ssenariyni ko'rib chiqing. Buni Prototip naqshidan foydalanib qanday amalga oshirishingiz mumkin:
import copy
class Employee:
def __init__(self):
self.name = None
self.role = None
self.department = None
def __str__(self):
return f"Xodim: Nomi={self.name}, Roli={self.role}, Bo'limi={self.department}"
class Prototype:
def __init__(self):
self._objects = {}
def register_object(self, name, obj):
self._objects[name] = obj
def unregister_object(self, name):
del self._objects[name]
def clone(self, name, **attrs):
obj = copy.deepcopy(self._objects.get(name))
if attrs:
obj.__dict__.update(attrs)
return obj
# Mijoz kodi
prototype = Prototype()
employee = Employee()
employee.name = "Umumiy xodim"
employee.role = "Dasturchi"
employee.department = "IT"
prototype.register_object("generic", employee)
employee1 = prototype.clone("generic", name="Jon Doe", role="Katta dasturchi")
employee2 = prototype.clone("generic", name="Jeyn Smit", role="Loyiha menejeri", department="Boshqaruv")
print(employee1)
# Natija: Xodim: Nomi=Jon Doe, Roli=Katta dasturchi, Bo'limi=IT
print(employee2)
# Natija: Xodim: Nomi=Jeyn Smit, Roli=Loyiha menejeri, Bo'limi=Boshqaruv
Xulosa
Yaratuvchan dizayn naqshlari ob'ekt yaratilishini moslashuvchan va saqlashga qulay tarzda boshqarish uchun kuchli vositalarni taqdim etadi. Ushbu naqshlarni tushunish va qo'llash orqali siz o'zgaruvchan talablarga moslashish va kengaytirish osonroq bo'lgan toza, yanada mustahkam kodni yozishingiz mumkin. Ushbu maqola beshta asosiy yaratuvchan naqshlarni - Singleton, Fabrika usuli, Abstrak fabrika, Builder va Prototip - amaliy misollar va real-dunyodagi foydalanish holatlari bilan o'rganib chiqdi. Ushbu naqshlarni o'zlashtirish malakali Python dasturchisi bo'lish yo'lidagi muhim qadamdir.
To'g'ri naqshni tanlash siz hal qilishga harakat qilayotgan muayyan muammoga bog'liqligini unutmang. Ob'ekt yaratishning murakkabligi, moslashuvchanlik zarurati va loyihangiz uchun yaratuvchan naqshni tanlashda kelajakdagi o'zgarishlar ehtimolini hisobga oling. Shunday qilib, siz umumiy dasturiy ta'minot dizayni muammolariga oqlangan va samarali echimlarni yaratish uchun dizayn naqshlarining kuchidan foydalanishingiz mumkin.