الأنماط السلوكية: Strategy وObserver وCommand
صمّم السلوك والتواصل باستخدام الأنماط السلوكية.
الأنماط السلوكية: Strategy وObserver وCommand درس مجاني في PHP Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في PHP Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة PHP Academy 4 دروس في المجموع.
نمذجة السلوك
تحكم الأنماط السلوكية كيفية تعاون الكائنات وتوزيع المسؤوليات. نركز على ثلاثة أنماط تظهر باستمرار في أنظمة PHP الواقعية:
- الاستراتيجية — تبديل خوارزمية أثناء التشغيل.
- المراقب — بث الأحداث إلى المستمعين المهتمين.
- الأمر — تحويل الطلب إلى كائن يمكن وضعه في قائمة انتظار أو تسجيله أو التراجع عنه.
الاستراتيجية: الفكرة
يعرّف نمط الاستراتيجية عائلة من الخوارزميات القابلة للتبديل خلف واجهة واحدة، ويتيح للعميل اختيار إحداها أثناء التشغيل. ويستبدل بنية switch المترامية أدناه بتعدد الأشكال؛ إذ يفوّض السياق المهمة إلى الاستراتيجية التي يحتفظ بها.
<?php
// The smell Strategy removes: branching on a type code
function price(string $type, float $base): float {
switch ($type) {
case 'standard': return $base + 5;
case 'express': return $base + 15;
default: throw new InvalidArgumentException($type);
}
}
echo price('express', 10), PHP_EOL; // 25
الاستراتيجية في الشيفرة
تعتمد تكلفة الشحن هنا على شركة النقل المختارة. وتغلف كل استراتيجية خوارزمية تسعير واحدة، بينما يظل السياق دون تغيير عند إضافة شركة نقل جديدة.
<?php
interface ShippingStrategy { public function cost(float $weight): float; }
final class Standard implements ShippingStrategy {
public function cost(float $w): float { return 5 + $w * 0.5; }
}
final class Express implements ShippingStrategy {
public function cost(float $w): float { return 15 + $w * 1.2; }
}
final class Cart {
public function __construct(private ShippingStrategy $strategy) {}
public function setStrategy(ShippingStrategy $s): void { $this->strategy = $s; }
public function quote(float $weight): float { return $this->strategy->cost($weight); }
}
$cart = new Cart(new Standard());
echo $cart->quote(10), PHP_EOL; // 10
$cart->setStrategy(new Express());
echo $cart->quote(10), PHP_EOL; // 27
الاستراتيجية مع الإغلاقات
لا تحتاج الاستراتيجية في PHP دائمًا إلى صنف. ففي الحالات الخفيفة، تُعد callable أو صياغة الاستدعاء القابل للاستخدام من الدرجة الأولى استراتيجيةً صحيحة تمامًا. استخدموا أصناف كاملة عندما تمتلك الخوارزمية حالتها أو اعتمادياتها الخاصة، واستخدموا الإغلاقات للاختيارات البسيطة عديمة الحالة.
<?php
$strategies = [
'asc' => fn(array $a) => sort($a) ? $a : $a,
'desc' => fn(array $a) => rsort($a) ? $a : $a,
];
$data = [3, 1, 2];
print_r($strategies['desc']($data)); // [3,2,1]
المراقب: الفكرة
يتيح نمط المراقب لـالموضوع إعلام العديد من المراقبين عند تغير حالته، من دون معرفة هوياتهم. ويفصل هذا مصدر الحدث عن معالجاته، ويشكّل أساس أنظمة الأحداث والخطافات والتحديثات التفاعلية.
المراقب في الشيفرة
يحتفظ الموضوع بقائمة من المراقبين، ويستدعي update() على كل واحد منهم. ويمكن للمستمعين الجدد الارتباط به من دون تغيير منطقه.
<?php
interface Observer { public function update(string $event): void; }
final class OrderSubject {
private array $observers = [];
public function subscribe(Observer $o): void { $this->observers[] = $o; }
public function placed(string $id): void {
foreach ($this->observers as $o) { $o->update("order $id placed"); }
}
}
final class EmailObserver implements Observer {
public function update(string $e): void { echo "email: $e" . PHP_EOL; }
}
final class AuditObserver implements Observer {
public function update(string $e): void { echo "audit: $e" . PHP_EOL; }
}
$subject = new OrderSubject();
$subject->subscribe(new EmailObserver());
$subject->subscribe(new AuditObserver());
$subject->placed('42');
المراقب مقارنةً بـ PSR-14
غالبًا ما تعبّر PHP الحديثة عن المراقب من خلال موزّعات الأحداث PSR-14؛ إذ يوجّه الموزّع كائن حدث إلى المستمعين المسجلين. والنموذجان متماثلان ذهنيًا: الموضوع = الحدث، والمراقبون = المستمعون، لكن الموزّع يفصل بينهما بدرجة أكبر ويدعم الأحداث القابلة للإيقاف. لا يزال SplObserver/SplSubject موجودًا في SPL، لكنه نادر الاستخدام اليوم.
الأمر: الفكرة
يغلّف نمط الأمر طلبًا في كائن، بما في ذلك الإجراء ومستقبِله ومعاملاته. وبما أن الطلب أصبح بيانات، يمكنكم وضعه في قائمة انتظار أو تسجيله أو إعادة المحاولة له أو التراجع عنه. والأمر الأبسط هو تحويل النية إلى قيمة صريحة، كما هو موضح أدناه.
<?php
final class SendEmail {
public function __construct(
public readonly string $to,
public readonly string $subject
) {}
}
// The request is now data you can store, serialize, or enqueue
$cmd = new SendEmail('user@example.com', 'Welcome');
echo json_encode($cmd), PHP_EOL;
الأمر في الشيفرة
يطبّق كل أمر execute(). ويحتفظ المستدعي بالأوامر ويشغّلها، منفصلًا عما تفعله. وتؤدي إضافة undo() إلى تحويل ذلك إلى مكدس تراجع كامل.
<?php
interface Command { public function execute(): string; }
final class Light { public bool $on = false; }
final class TurnOn implements Command {
public function __construct(private Light $light) {}
public function execute(): string { $this->light->on = true; return 'light on'; }
}
final class TurnOff implements Command {
public function __construct(private Light $light) {}
public function execute(): string { $this->light->on = false; return 'light off'; }
}
final class Invoker {
private array $queue = [];
public function add(Command $c): void { $this->queue[] = $c; }
public function run(): void {
foreach ($this->queue as $c) { echo $c->execute(), PHP_EOL; }
}
}
$light = new Light();
$inv = new Invoker();
$inv->add(new TurnOn($light));
$inv->add(new TurnOff($light));
$inv->run();
حافلات الأوامر
تبني أطر العمل حافلة أوامر اعتمادًا على هذا النمط؛ إذ يُرسل كائن DTO يمثل الأمر إلى معالج واحد بالضبط. ويمكن للبرمجيات الوسيطة المحيطة بالحافلة إضافة المعاملات والتحقق والتسجيل بصورة موحدة. وبما أن الأوامر كائنات عادية قابلة للتسلسل، يمكن للمعالج نفسه أن يعمل بصورة متزامنة أو أن يُدفع إلى عامل قائمة انتظار.
الاختيار من بينها
- الاستراتيجية: عملية واحدة وخوارزميات متعددة قابلة للتبديل، يختارها المستدعي.
- المراقب: حدث واحد وردود فعل مستقلة متعددة، من دون أن يعرف المصدر معالجاته.
- الأمر: تحويل الطلب إلى كائن بحيث يمكن وضعه في قائمة انتظار أو تسجيله أو إعادة المحاولة له أو التراجع عنه.
تتآزر هذه الأنماط جيدًا؛ فقد يختار معالج أمر استراتيجيةً ويصدر أحداثًا للمراقبين.
فحص سريع
طابقوا المتطلب مع النمط المناسب.
مراجعة
نمذجتم السلوك باستخدام ثلاثة أنماط: الاستراتيجية لتبديل الخوارزميات أثناء التشغيل، سواء باستخدام الأصناف أو الإغلاقات، والمراقب لبث تغييرات الحالة إلى مستمعين منفصلين، وهو أساس موزّعات PSR-14، والأمر لتحويل الطلبات إلى كائنات يمكن وضعها في قائمة انتظار أو تسجيلها أو التراجع عنها، وهو أساس حافلات الأوامر. وتحافظ هذه الأنماط مجتمعةً على مرونة التعاون ووضوح المسؤوليات.
الأسئلة الشائعة
هل درس «الأنماط السلوكية: Strategy وObserver وCommand» مجاني؟
نعم — نص درس «الأنماط السلوكية: Strategy وObserver وCommand» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة PHP Academy، انتقل إلى CoddyKit PRO. تتضمن دورة PHP Academy 4 دروس في المجموع.
ماذا ستتعلم في «الأنماط السلوكية: Strategy وObserver وCommand»؟
صمّم السلوك والتواصل باستخدام الأنماط السلوكية. تتمرن على PHP Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ PHP Academy؟
لا تُشترط خبرة سابقة. PHP Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «الأنماط السلوكية: Strategy وObserver وCommand»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس PHP Academy هذا؟
نعم. كل درس في PHP Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- مبادئ SOLID في التطبيق
- الأنماط الإنشائية: Factory وBuilder وSingleton
- الأنماط الهيكلية: Adapter وDecorator وFacade
- الأنماط السلوكية: Strategy وObserver وCommand