2.6. Facade¶
2.6.1. تعریف¶
دیزاین پترن Facade یک الگوی ساختاری محسوب میشه که به ما اجازه میده یک interface ساده برای یک سیستم پیچیده فراهم کنیم.
با این کار لایه های پیچیده ی برنامه رو از دید سطوح بالاتر پنهان می کنیم و اجازه میدیم خیلی راحت تر بشه با برنامه در ارتباط بود.
این الگوی طراحی یکی از پراستفاده ترین الگو ها در فریمورک های مختلف محسوب میشه.
2.6.2. اجزاء¶
یک دیزاین پترن Facade از دو بخشی اصلی به اضافه Client تشکیل میشه.
مهم ترین بخش که سیستم نهایی سطح بالا با اون سر و کار داره بخش Facade هست که شامل یک interface ساده برای کار کردن با بخش های مختلف سیستم پیچیده یا زیر سیستم ها (Subsystems) محسوب میشه.
زیر سیستم ها component های مستقل سیستم هستن که هر کدوم وظایف مشخصی دارن و تلاش ما اینه که پیچیدگی این زیر سیستم ها رو از دید لایه سطح بالای برنامه پنهان کنیم.
Original Vanderjoe Vector: FeRDNYC, CC BY-SA 4.0, via Wikimedia Commons
2.6.3. چه زمانی استفاده میشه؟¶
این الگو رو زمانی استفاده می کنیم که با یک سیستم نسبتا پیچیده طرف هستیم که قرار نیست سطوح بالای برنامه اطلاعی از این پیچیدگی داشته باشن، پس در این شرایط سعی می کنیم روش ساده تری برای دسترسی سطوح بالا به عملکرد های مختلف این سیستم فراهم کنیم.
Caution
✅ مزایای استفاده
حذف پیچیدگی برنامه برای سطوح بالاتر برنامه
Warning
❌ معایب استفاده
یک Facade ممکنه تبدیل به یک آبجکت خیلی بزرگ با قابلیت های خیلی زیاد بشه که به تعداد زیادی کلاس متصله (God Object)
2.6.4. کاربرد عملی¶
تصور کنید یک سری کلاس داریم که هر کدوم مربوط به بخشی از عملیات پرداخت هستن و قرار نیست سطوح بالا رو درگیر کار با تمام این کلاس ها کنیم.
اینجاست که استفاده از دیزاین پترن Facade میتونه مفید باشه.
2.6.5. پیاده سازی¶
زیر سیستم های ما شامل کلاس های زیر هستن:
1<?php
2
3// Define the subsystems
4class OrderVerification
5{
6 public function verifyOrder(int $orderId): bool
7 {
8 // Code to verify the order
9 return true;
10 }
11}
12
13class PaymentProcessor
14{
15 public function processPayment(float $amount): bool
16 {
17 // Code to process the payment
18 return true;
19 }
20}
21
22class OrderFulfillment
23{
24 public function fulfillOrder(int $orderId): bool
25 {
26 // Code to fulfill the order
27 return true;
28 }
29}
که مراحل مختلف پرداخت رو مدیریت می کنن.
و کلاس Facade رو به این صورت تعریف می کنیم:
1<?php
2
3// Define the facade
4class OrderFacade
5{
6 protected OrderVerification $verification;
7 protected PaymentProcessor $payment;
8 protected OrderFulfillment $fulfillment;
9
10 public function __construct()
11 {
12 $this->verification = new OrderVerification();
13 $this->payment = new PaymentProcessor();
14 $this->fulfillment = new OrderFulfillment();
15 }
16
17 public function placeOrder(int $orderId, float $amount): bool
18 {
19 $verified = $this->verification->verifyOrder($orderId);
20
21 if (!$verified) {
22 return false;
23 }
24
25 $paid = $this->payment->processPayment($amount);
26
27 if (!$paid) {
28 return false;
29 }
30
31 $fulfilled = $this->fulfillment->fulfillOrder($orderId);
32
33 if (!$fulfilled) {
34 return false;
35 }
36
37 return true;
38 }
39}
پس این کلاس Facade هست که با این پیچیدگی مواجه میشه و اون رو در نهایت تبدیل به یک متد به نام placeOrder می کنه.
2.6.6. نحوه فراخوانی¶
1<?php
2
3// Client code
4$facade = new OrderFacade();
5$orderId = 12345;
6$amount = 99.99;
7
8if ($facade->placeOrder($orderId, $amount)) {
9 echo "Order placed successfully.\n";
10} else {
11 echo "Failed to place order.\n";
12}
و کد سطح بالای ما در نهایت فقط از ساختار Facade اطلاع داره و از لایه های زیرین برنامه یعنی زیر سیستم ها مطلع نمیشه.