() translation by (you can also view the original English article)
عندما يتعلق الأمر بأنماط التصاميم أو مايعرف بنماذج التصاميم قد يجول في ذهنك بعض الأسئلة :
لماذا يتوجب علينا إستخدام أنماط التصاميم في البرمجة؟ برنامجي يعمل بشكل جيد دون الحاجة لهذه الأنماط.
سأقوم بطرح سؤال مباغت لهذا السؤال: هل تفضل العيش في بيت فخم , او بيت بسيط يمتلك أربعة جدران؟ في النهاية الأثنين يحققان نفس الغاية.
بشكل عام, كبشر نحن نحب البيوت الفارهة لأنها تقدم تسهيلات أكثر وتتطلب صيانة أقل, حتى الصيانة المطلوبة تكون سهلة جدا لأن البناء الأساسي قد تم بشكل جيد وصحيح.
هذا الشيء ينطق نفسه تماماً على البرمجة. الكود الذي نستخدم فيه أنماط التصاميم هو كود سهل الفهم, سهل الصيانة وسهل التوسع.
في هذه الدروس, سوف أقوم بإستخدام لغة ال PHP لتمثل أنماط التصاميم, ولكن مبدأ أنماط التصاميم هو ليس حكر على لغة معينة وأنما هو مبدأ يمكن تطبيقة في اية لغة برمجة. كل ماهنالك أن الترميز يختلف حسب اللغة المفضلة او المستخدمة.
قد تم تقسيم قواعد أنماط التصاميم إلى 4 فئات:
- أنماط التصاميم الإنشائية
- أنماط التصاميم الهيكلية
- أنماط التصاميم السلوكية
- أنماط التصاميم المتزامنة
في هذا الدرس , سوف نقوم بتغطية نمط الواجهة Facade . حيث أن هذا النمط متضمن ضمة فئة التصاميم الهيكلية , لأنه يتحكم بكيفية هيكلة الكود الخاص بتطبيقك , لجعله اوضح واسهل في الصيانة على المدى الطويل.
نمط تصميم الواجهة:Facade
The UML حالة الإستخدام



المشكلة :
دعونا نعتبر أنه لدينا مجموعة عمليات يجب تنفيذها بشكل تسلسلي, وتنفيذ هذه العمليات مكرر في أماكن عدة من التطبيق الخاص بك. في الوضع العادي سوف تقوم بنسخ نفس الكود بشكل مكرر في كل مكان تحتاج هذا التسلسل من العمليات وقد تكون بالفعل قد قمت بفعل ذلك! ولكن بعد عدة أيام تكتشف أنك بحاجة تغيير شيء في هذه القطعة المكررة من الكود.
هل ترى المشكلة بشكل واضح؟ نعم يجب علينا أن نقوم بالتغيير في كل الأماكن الذي قمنا بنسخ الكود إليها. هذه العملية مرهقة وغير مضمونة, أليس كذلك؟
Solution
كحل لهذه المشكلة , يمكنك إنشاء متحكم قيادي يتضمن هذه الكود المكرر . من وجهة نظر الأستدعاء, سوف نقوم فقط بإستدعاء هذا المتحكم وتنفيذ العملية المطلوبة حسب معطيات الدخل من جميع النقاط المختلفة.
في هذه الحالة, عندما نحتاج إلى تغيير سلسلة العمليات التي قمنا بتجميعها في هذا المتحكم, لن نحتاج إلى تغيير سوى مكان واحد هو المتحكم! وهذا بالطبع افضل من السابق حيث كان من المتوجب علينا تذكر جميع الأماكن التي قمنا بتكرير الكود بها.
مثال من الواقع:
في هذا الدرس, دعونا نختار مثال واحد لشرح الموضوع بشكل أفضل. دعونا نقول أنه قد اعطيت مهمة لتخطيط حفل زفاف أحد اصدقائك. في هذه الحالة إذا قمت بإتخاذ قرار تنظيم كل شيء بمفردك, سوف يكون إحتمال حدوث الخطأ أكبر بكثير, ومن المككن كثيرا ان تنسى شيء مهم قد يسبب بفشل حفلة زفاف صديقك!
في هذه الحالة, عوض عن أن تقوم بفعل كل شيء بمفردك, الحل الأمثل هو أن تقوم بالإستعانة بمنظم حفلات زفاف, والتأكد من أن العمل قد تم السيطرة عليه بنجاح دون إحتمال حدوث أخطاء.
في هذه المثال كان دورك الأساسي هو تهيئة العملية, ومنظم الحفلات كان "الواجهة" التي قامت بتنفيذ العمل على المستوى المطلوب.
مثال كود :
في هذا القسم سوف نقوم بإستخدام مثال متداول كثيراً في الويب. سوف نقوم بتطبيق نمط تصميم الواجهة بإستخدام شراء منتج. ولكن قبل ان ترى كود مثالي بإستخدام نمط تصميم الواجهة, دعونا نرى المشكلة اولا دون إستخدام هذا النمط :
عملية الدفع لمنتج أون لاين , تطلب الخطوات التالية :
- إضافة المنتج إلى سلة التسوق
- حساب تكلفة الشحن
- حساب الخصومات إن وجد
- توليد الطلب
المشكلة :
1 |
// Simple CheckOut Process |
2 |
$productID = $_GET['productId']; |
3 |
|
4 |
$qtyCheck = new productQty(); |
5 |
|
6 |
if($qtyCheck->checkQty($productID) > 0) { |
7 |
|
8 |
// Add Product to Cart |
9 |
$addToCart = new addToCart($productID); |
10 |
|
11 |
// Calculate Shipping Charge |
12 |
$shipping = new shippingCharge(); |
13 |
$shipping->updateCharge(); |
14 |
|
15 |
// Calculate Discount Based on |
16 |
$discount = new discount(); |
17 |
$discount->applyDiscount(); |
18 |
|
19 |
$order = new order(); |
20 |
$order->generateOrder(); |
21 |
}
|
في الكود السابق, سوف نرى أن آلية الدفع تتضمن أغراض مختلفة لتكامل هذه العملية. تخيل بأنك تحتاج هذه العملية في أماكن مختلفة. طبعا في هذه الحالة وعند الحاجة لتعديل الكود أو جعله أفضل سوف نواجه المشكلة السابقة البحث عن اماكن الكود المكرر! من الأفضل جعل هذه التغيرات كلها في مكان واحد.
الحل:
سوف نقوم بكتابة نفس الكود السابق مع تطبيق نمط تصميم الواجهة. وهذا سوف يجعل الكود قابل للصيانة والتمدد لاحقاً
1 |
class productOrderFacade { |
2 |
|
3 |
public $productID = ''; |
4 |
|
5 |
public function __construct($pID) { |
6 |
$this->productID = $pID; |
7 |
}
|
8 |
|
9 |
public function generateOrder() { |
10 |
|
11 |
if($this->qtyCheck()) { |
12 |
|
13 |
// Add Product to Cart
|
14 |
$this->addToCart(); |
15 |
|
16 |
// Calculate Shipping Charge
|
17 |
$this->calulateShipping(); |
18 |
|
19 |
// Calculate Discount if any
|
20 |
$this->applyDiscount(); |
21 |
|
22 |
// Place and confirm Order
|
23 |
$this->placeOrder(); |
24 |
|
25 |
}
|
26 |
|
27 |
}
|
28 |
|
29 |
private function addToCart () { |
30 |
/* .. add product to cart .. */
|
31 |
}
|
32 |
|
33 |
private function qtyCheck() { |
34 |
|
35 |
$qty = 'get product quantity from database'; |
36 |
|
37 |
if($qty > 0) { |
38 |
return true; |
39 |
} else { |
40 |
return true; |
41 |
}
|
42 |
}
|
43 |
|
44 |
|
45 |
private function calulateShipping() { |
46 |
$shipping = new shippingCharge(); |
47 |
$shipping->calculateCharge(); |
48 |
}
|
49 |
|
50 |
private function applyDiscount() { |
51 |
$discount = new discount(); |
52 |
$discount->applyDiscount(); |
53 |
}
|
54 |
|
55 |
private function placeOrder() { |
56 |
$order = new order(); |
57 |
$order->generateOrder(); |
58 |
}
|
59 |
}
|
في هذه اللحظة, لدينا نمط واجهة جاهزة للإستخدام. كل ماعلينا هو إستخدام كود إستدعائي , عوضاً عن إستخدام كومة من السطور كما كانت موجودة سابقاً!
يرجى الأنتباه لكمية الكود التي سيتم وضعها الآن لإستدعاء المتحكم "نمط تصميم الواجهة" عوضاً عن كومة الكود التى استخدمناها عند طرح المشكلة. يمكن تكرار هذا الإستداعاء في جميع الأماكن عند الحاجة بالطبع :
1 |
// Note: We should not use direct get values for Database queries to prevent SQL injection
|
2 |
$productID = $_GET['productId']; |
3 |
|
4 |
// Just 2 lines of code in all places, instead of a lengthy process everywhere
|
5 |
$order = new productOrderFacade($productID); |
6 |
$order->generateOrder(); |
الآن تخيل أنك قد احتجت لتغيير عملية الدفع. ببساطة يمكنك تغيير صف الواجهة الذي قمت بإنشائه, عوضاً عن البحث في ملفات صفوفك عن المكان الذي قمت بنسخ عملية الدفع مرات عدة!
النتيجة:
ببساطة , يمكننا قول أنه يجب إستخدام نمط تصميم الواجهة عند الحاجة إلى واجهة وحيدة لإتمام عدة عمليات, كمثال منظم حفلات الزفاف الذي يمثل الواجهة التي تقوم بعمليات متعددة.
الآن بإمكانكم وضع تعليق لمعرفة أرائكم.