Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

نمط Observer

جزء من قسم Object Oriented Programming في رحلة Python على Coddy — الدرس 47 من 64.

ينشئ نمط المراقب (Observer Pattern) علاقة واحد إلى متعدد حيث يقوم كائن واحد (الموضوع - subject) بإخطار كائنات متعددة (المراقبين - observers) عندما تتغير حالته.

إليك فئة Subject بسيطة تدير المراقبين:

class Subject:
    def __init__(self):
        self._observers = []
    
    def add_observer(self, observer):
        self._observers.append(observer)
    
    def notify(self, message):
        for observer in self._observers:
            observer.update(message)

يحتفظ الموضوع بقائمة من المراقبين ويمكنه إخطارهم جميعاً في وقت واحد.

قم بإنشاء فئات مراقب (observer) بسيطة:

class EmailNotifier:
    def update(self, message):
        print(f"Email sent: {message}")

class SMSNotifier:
    def update(self, message):
        print(f"SMS sent: {message}")

لكل مراقب دالة update يتم استدعاؤها عند التنبيه.

استخدم نمط المراقب (Observer Pattern):

# إنشاء الموضوع
news = Subject()

# إنشاء المراقبين
email = EmailNotifier()
sms = SMSNotifier()

# إضافة المراقبين إلى الموضوع
news.add_observer(email)
news.add_observer(sms)

# إخطار جميع المراقبين
news.notify("Breaking news: Python is awesome!")

أنشئ مثالاً عملياً باستخدام متتبع لأسعار الأسهم:

class Stock:
    def __init__(self, symbol, price):
        self.symbol = symbol
        self._price = price
        self._observers = []
    
    def add_observer(self, observer):
        self._observers.append(observer)
    
    def set_price(self, price):
        self._price = price
        self.notify()
    
    def notify(self):
        for observer in self._observers:
            observer.update(self.symbol, self._price)

class Investor:
    def __init__(self, name):
        self.name = name
    
    def update(self, symbol, price):
        print(f"{self.name} notified: {symbol} is now ${price}")

# استخدام متتبع الأسهم
apple_stock = Stock("AAPL", 150)

investor1 = Investor("Alice")
investor2 = Investor("Bob")

apple_stock.add_observer(investor1)
apple_stock.add_observer(investor2)

apple_stock.set_price(155)  # يقوم بإخطار جميع المستثمرين

المخرجات:

Email sent: Breaking news: Python is awesome!
SMS sent: Breaking news: Python is awesome!
Alice notified: AAPL is now $155
Bob notified: AAPL is now $155

نقطة رئيسية: يسمح نمط المراقب (Observer Pattern) لكائن واحد بإخطار العديد من الكائنات الأخرى تلقائيًا عند حدوث تغيير ما. يحتفظ الموضوع (subject) بقائمة من المراقبين (observers) ويستدعي أسلوب update الخاص بهم عند الحاجة. هذا مفيد للإشعارات، وأنظمة الأحداث، والحفاظ على مزامنة أجزاء متعددة من تطبيقك.

challenge icon

التحدي

متوسط

قم بتنفيذ نمط المراقب (Observer Pattern) من خلال إنشاء نظام لمراقبة الطقس. تحتاج إلى إنشاء فئتين (classes) في المناطق المخصصة من الكود.

الخطوة 1: إنشاء فئة WeatherStation

اكتب فئة WeatherStation الخاصة بك حيث يشير التعليق. يجب أن تقوم هذه الفئة بما يلي:

  • الوراثة من فئة Subject (استخدم class WeatherStation(Subject):)
  • التهيئة باستخدام:
    • استدعاء منشئ الفئة الأم باستخدام super().__init__()
    • تعيين درجة الحرارة الأولية إلى 0 باستخدام سمة خاصة self._temperature
  • تنفيذ <strong>set_temperature(self, temperature)</strong>:
    • تحديث سمة درجة الحرارة الخاصة
    • استدعاء self.notify(self._temperature) لإخطار جميع المراقبين
  • تنفيذ <strong>get_temperature(self)</strong>:
    • إرجاع قيمة درجة الحرارة الحالية

الخطوة 2: إنشاء فئة WeatherDisplay

اكتب فئة WeatherDisplay الخاصة بك حيث يشير التعليق. يجب أن تقوم هذه الفئة بما يلي:

  • الوراثة من فئة Observer (استخدم class WeatherDisplay(Observer):)
  • التهيئة باستخدام:
    • قبول معامل name
    • تخزين الاسم كـ self.name
  • تنفيذ <strong>update(self, temperature)</strong>:
    • طباعة رسالة تحديث درجة الحرارة بالتنسيق الدقيق الموضح أدناه

تنسيق الرسالة:

عندما تتلقى شاشة العرض تحديثاً لدرجة الحرارة، يجب أن تطبع تماماً:

Display [name]: Current temperature is [temperature]C

مثال على الاستخدام:

# Create weather station and displays
station = WeatherStation()
phone_display = WeatherDisplay("Phone")
tablet_display = WeatherDisplay("Tablet")

# Attach displays to station
station.attach(phone_display)
station.attach(tablet_display)

# Update temperature - both displays will be notified
station.set_temperature(25.5)

# Output:
# Display Phone: Current temperature is 25.5C
# Display Tablet: Current temperature is 25.5C

ملاحظات هامة:

  • الأساليب (methods) attach() و detach() منفذة بالفعل في الفئة الأساسية Subject - لست بحاجة لتنفيذها أو استدعائها داخل فئة WeatherStation الخاصة بك
  • في مثال الاستخدام أعلاه، يتم استدعاء station.attach(phone_display) بواسطة مستخدم الفئة الخاصة بك، وليس داخل تنفيذ WeatherStation
  • تحتاج WeatherStation فقط إلى استدعاء self.notify() عندما تتغير درجة الحرارة - وتتولى الفئة الأساسية Subject الباقي
  • ركز على تنفيذ الأساليب الثلاثة المطلوبة في WeatherStation والأسلوبين المطلوبين في WeatherDisplay كما هو محدد أعلاه

ورقة مرجعية

ينشئ نمط المراقب (Observer Pattern) علاقة واحد إلى متعدد حيث يقوم كائن واحد (الموضوع - subject) بإخطار كائنات متعددة (المراقبون - observers) عندما تتغير حالته.

فئة الموضوع (Subject) الأساسية التي تدير المراقبين:

class Subject:
    def __init__(self):
        self._observers = []
    
    def add_observer(self, observer):
        self._observers.append(observer)
    
    def notify(self, message):
        for observer in self._observers:
            observer.update(message)

فئات المراقب (Observer) مع طريقة update:

class EmailNotifier:
    def update(self, message):
        print(f"Email sent: {message}")

class SMSNotifier:
    def update(self, message):
        print(f"SMS sent: {message}")

استخدام نمط المراقب:

# إنشاء الموضوع
news = Subject()

# إنشاء المراقبين
email = EmailNotifier()
sms = SMSNotifier()

# إضافة المراقبين إلى الموضوع
news.add_observer(email)
news.add_observer(sms)

# إخطار جميع المراقبين
news.notify("Breaking news: Python is awesome!")

مثال عملي مع متتبع أسعار الأسهم:

class Stock:
    def __init__(self, symbol, price):
        self.symbol = symbol
        self._price = price
        self._observers = []
    
    def add_observer(self, observer):
        self._observers.append(observer)
    
    def set_price(self, price):
        self._price = price
        self.notify()
    
    def notify(self):
        for observer in self._observers:
            observer.update(self.symbol, self._price)

class Investor:
    def __init__(self, name):
        self.name = name
    
    def update(self, symbol, price):
        print(f"{self.name} notified: {symbol} is now ${price}")

يتيح نمط المراقب لكائن واحد إخطار العديد من الكائنات الأخرى تلقائياً عند حدوث تغيير ما. يحتفظ الموضوع بقائمة من المراقبين ويستدعي طريقة update الخاصة بهم عند الحاجة.

جرّب بنفسك

class Subject:
    def __init__(self):
        self._observers = []
    
    def attach(self, observer):
        self._observers.append(observer)
        
    def detach(self, observer):
        self._observers.remove(observer)
        
    def notify(self, data):
        for observer in self._observers:
            observer.update(data)
            
class Observer:
    def update(self, data):
        pass

# اكتب فئة WeatherStation الخاصة بك هنا

# اكتب فئة WeatherDisplay الخاصة بك هنا

quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming