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

نمط Observer

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

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

فكّر في الاشتراك في newsletter. newsletter هو الموضوع، والمشتركون هم observers. عند نشر إصدار جديد، يتلقّى جميع المشتركون هذا الإصدار تلقائيًا من دون أن تحتاج newsletter إلى معرفة تفاصيل كل مشترك.

إليك تطبيقًا أساسيًا بلغة PHP:

<?php
interface Observer {
    public function update(string $message): void;
}

class Newsletter {
    private array $subscribers = [];
    
    public function subscribe(Observer $observer): void {
        $this->subscribers[] = $observer;
    }
    
    public function publish(string $content): void {
        foreach ($this->subscribers as $subscriber) {
            $subscriber->update($content);
        }
    }
}

class EmailSubscriber implements Observer {
    public function __construct(private string $email) {}
    
    public function update(string $message): void {
        echo "Sending to {$this->email}: $message\n";
    }
}

$newsletter = new Newsletter();
$newsletter->subscribe(new EmailSubscriber("alice@example.com"));
$newsletter->subscribe(new EmailSubscriber("bob@example.com"));
$newsletter->publish("New article released!");

المخرجات:

Sending to alice@example.com: New article released!
Sending to bob@example.com: New article released!

يفصل هذا النمط الكائن عن المراقبين التابعين له. لا تحتاج الفئة Newsletter إلى معرفة ما إذا كانت تُرسل إشعارات إلى مشتركي البريد الإلكتروني، أو مشتركي SMS، أو خدمات الإشعارات الفورية. فهي تستدعي ببساطة update() على أي شيء يطبّق الواجهة Observer. وهذا يجعل إضافة أنواع جديدة من المراقبين أمرًا سهلًا دون تعديل الشيفرة الموجودة.

challenge icon

التحدي

سهل

لنَبْنِ نظامًا للتنبيه عند تغيّر سعر السهم باستخدام نمط Observer. عندما يتغير سعر سهم، ينبغي إخطار جميع المستثمرين المسجلين تلقائيًا: وهذا تطبيق مثالي واقعي لهذا النمط.

ستنظّم شيفرتك عبر أربعة ملفات:

  • Observer.php: عرّف واجهة Observer ذات method واحدة هي update(string $stockName, float $price): void. وهذا هو العقد الذي يجب على جميع observers اتباعه لتلقي notifications.
  • Investors.php: ضمّن ملف Observer وأنشئ classين ينفّذان الواجهة:
    • EmailInvestor: يستقبل عنوان email في constructor الخاص به (استخدم constructor promotion). تطبع method update() الخاصة به "Email to [email]: [stockName] is now $[price]"
    • SmsInvestor: يستقبل رقم phone في constructor الخاص به. تطبع method update() الخاصة به "SMS to [phone]: [stockName] is now $[price]"
  • Stock.php: ضمّن ملف Observer وأنشئ class باسم Stock يتصرف بصفته subject. يجب أن يقوم سهمك بما يلي:
    • تخزين اسم السهم والسعر الحالي (استخدم constructor promotion للاسم، وInitialize السعر إلى 0.0)
    • Maintain مصفوفة خاصة من observers
    • امتلاك method باسم subscribe(Observer $observer): void لإضافة observers
    • امتلاك method باسم setPrice(float $price): void تحدّث السعر وتُخطِر all observers
    عند إخطار observers، استدعِ method update() لكل observer مع اسم السهم والسعر الجديد.
  • main.php: ضمّن ملفَي Investors وStock. ستتلقى ثلاثة inputs: اسم سهم، وعنوان email، ورقم phone.

    أنشئ Stock بالاسم given. سجّل EmailInvestor باستخدام عنوان email وSmsInvestor باستخدام رقم phone.

    اضبط سعر السهم على 150.50 لإطلاق notifications إلى جميع المشتركين.

يحافظ نمط Observer على فصل class Stock عن methods الإخطار المحددة. ويمكنك بسهولة إضافة PushInvestor أو SlackInvestor لاحقًا من دون تعديل class Stock على الإطلاق.

جرّب بنفسك

<?php
require_once 'Investors.php';
require_once 'Stock.php';

// اقرأ المدخلات
$stockName = trim(fgets(STDIN));
$email = trim(fgets(STDIN));
$phone = trim(fgets(STDIN));

// TODO: أنشئ Stock بالاسم المعطى

// TODO: اشترك EmailInvestor بعنوان البريد الإلكتروني

// TODO: اشترك SmsInvestor برقم الهاتف

// TODO: عيّن سعر السهم إلى 150.50 لتفعيل الإشعارات
?>
quiz iconاختبر نفسك

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

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

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