Загрузка...

🎓 Python design patterns: singleton, factory, observer Explained | Python Tutorial for Beginners

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎓 CONCEPT: PYTHON DESIGN PATTERNS: SINGLETON, FACTORY, OBSERVER
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Design patterns are reusable solutions to common software design problems, helping to make code more organized, maintainable, and scalable. They provide a blueprint for solving specific issues, allowing developers to build more robust applications. Here, we will explore three fundamental design patterns in Python: Singleton, Factory, and Observer.

Key Points:

1. Singleton Pattern:
The Singleton pattern ensures that a class has only one instance and provides a single, global point of access to it. This is useful for managing resources that should not be duplicated, such as database connections, configuration settings, or a logging system. In Python, a common way to implement the Singleton pattern is by controlling the object creation process using the `__new__` method. When an instance is requested, Python first calls `__new__` to create the object. A Singleton implementation will check if an instance already exists; if not, it creates one and stores it, then returns the stored instance on subsequent requests.

Practical Example:
Imagine a configuration manager for an application. You only want one instance of this manager to hold all application settings so that it's consistent across the entire application.

class SingletonConfig:
_instance = None

def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls, *args, **kwargs)
# Initialize configuration here if needed
cls._instance.settings = {"theme": "dark", "timeout": 30}
return cls._instance

# Usage
config1 = SingletonConfig()
config2 = SingletonConfig()

print(f"config1 is config2: {config1 is config2}")
print(f"Settings: {config1.settings}")

Output:
config1 is config2: True
Settings: {'theme': 'dark', 'timeout': 30}

2. Factory Pattern:
The Factory pattern decouples the object creation logic from the rest of the code. Instead of directly instantiating classes, you use a factory method or class that is responsible for creating objects. This is particularly helpful when you have multiple related classes and need to decide which one to instantiate based on certain conditions or input. The factory hides the complexity of object creation, making the code cleaner and easier to manage.

Practical Example:
Consider a system that needs to create different types of notification messages (e.g., email, SMS, push notification). A factory can decide which notification class to instantiate based on a type string.

class EmailNotifier:
def send(self, message):
print(f"Sending email: {message}")

class SmsNotifier:
def send(self, message):
print(f"Sending SMS: {message}")

class NotificationFactory:
@staticmethod
def create_notifier(notifier_type):
if notifier_type == "email":
return EmailNotifier()
elif notifier_type == "sms":
return SmsNotifier()
else:
raise ValueError("Unknown notifier type")

# Usage
factory = NotificationFactory()
email_sender = factory.create_notifier("email")
sms_sender = factory.create_notifier("sms")

email_sender.send("Hello via email!")
sms_sender.send("Hello via SMS!")

Output:
Sending email: Hello via email!
Sending SMS: Hello via SMS!

3. Observer Pattern:
The Observer pattern defines a one-to-many dependency between objects. When the state of one object (the "subject" or "observable") changes, all its dependent objects (the "observers") are automatically notified and updated. This pattern is fundamental for building event-driven or reactive systems, promoting loose coupling between objects. An observer subscribes to a subject, and the subject maintains a list of these subscribers, notifying them when its state changes.

Practical Example:
Imagine a weather station (the subject) that reports temperature changes. Multiple display devices (observers) need to be updated whenever the temperature changes.

class WeatherStation:
def __init__(self):
self._observers = []
self._temperature = 0

def attach(self, observer):
self._observers.append(observer)

def detach(self, observer):
self._observers.remove(observer)

def notify_observers(self):
for observer in self._observers:
observer.update(self._temperature)

@property
def temperature(self):
return self._temperature

@temperature.setter
def temperature(self, value):
self._temperature = value
self.notify_observers()

class TemperatureDisplay:
def __init__(self, name):
self.name = name

def update(self, temperature):
print(f"{self.name} updated: Current temperature is {temperature}°C")

# Usage
station = WeatherStation()
display1 = TemperatureDisplay("Display 1")
display2 = TemperatureDisplay("Display 2")

station.attach(display1)
st...

Видео 🎓 Python design patterns: singleton, factory, observer Explained | Python Tutorial for Beginners канала wong's learning
Яндекс.Метрика
Все заметки Новая заметка Страницу в заметки
Страницу в закладки Мои закладки
На информационно-развлекательном портале SALDA.WS применяются cookie-файлы. Нажимая кнопку Принять, вы подтверждаете свое согласие на их использование.
О CookiesНапомнить позжеПринять