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

نمط Observer

جزء من قسم البرمجة كائنية التوجه في رحلة Python على Coddy. الدرس 47 من 64.

ينشئ نمط المراقب علاقةً واحدًا إلى متعدد، حيث يُخطِر كائن واحد (الموضوع) عدة كائنات (المراقبين) عند تغيّر حالته.

إليك فئة 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)

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

أنشئ فئات مراقِبة بسيطة:

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

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

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

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

# إنشاء الموضوع
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

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

challenge icon

التحدي

متوسط

نفّذ نمط المراقب من خلال إنشاء نظام لمراقبة الطقس. تحتاج إلى إنشاء فئتين في المناطق المحددة من الكود.

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

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

  • الوراثة من الفئة Subject (استخدم class WeatherStation(Subject):)
  • التهيئة باستخدام:
    • استدعِ مُنشئ الفئة الأصلية باستخدام super().__init__()
    • اضبط درجة الحرارة الأولية على 0 باستخدام السمة ذات الشرطة السفلية المفردة self._temperature (وهي اصطلاح Python للسمة الداخلية)
  • تنفيذ <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

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

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

جرّب بنفسك

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اختبر نفسك

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

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم Python عبر الإنترنت