() translation by (you can also view the original English article)
عندما تفكر في كلمة مصنع, ماهو الشي الذي يجول في خاطرك؟ بالنسبة لي, المصنع هو المكان الذي تُصنّع فيه الأشياء -أي هو المكان المركزي الذي تنتج فيه الاغراض. حيث أنه يتم إنهاء هذه الأغراض في المصنع بحسب ترتيب معطيات الطلب.
على سبيل المثال, لنعتبر بأنك قمت بطلب سيارة. المصنع سيقوم بتصنيع السيارة لك بالترتيب المناسب لإنهائها , وسيقوم بتوصيلها عندما تكون جاهزة بالطبع.
البرمجة تماثل تماما طبيعة العالم الحقيقي. حيث أن برمجية المصنع ( برمجية تعمل على تنفيذ نمط المصنع) هي غرض (Object) مسؤول عن إنشاء أغراض أخرى وإيصالها لأغراض تقوم بطلبها وفقا لمتحولات الدخل الموجودة فيها.
هالك ثلاثة أشكال مختلفة لنمط المصنع::
- نمط المصنع البسيط: يسمح للواجهات interfaces بإنشاء أغراض دون عرض كيفية إنشاء الغرض للزبون.
- -نمط وظيفة المصنع او Factory Method : يسمح للواجهات بإنشاء أغراض مع السماح للصفوف الأبناء بتحديد أي الصفوف التي يمكن إنشاؤها.
- نمط المصنع المجرد : وهو مختلف عن النمطين السابقين. المصنع المجرد هو واجهة لإنشاء أغراض مترابطة دون الحاجة لتحديد صفوف هذه الأغراض. يمكننا القول بأنها تزود الغرض بمصنع آخر الذي بدوره يكون هو المسؤول عن صنع هذه الأغراض.
المشكلة :
دعونا نتخيل أنه لدينا صف سيارة , هذا الصف هو المسؤول عن إنشاء عربة بكل الخصائص والطرق المضمنة فيه. بأبسط الطرق ماعليك سوى أن تقوم بإنشاء الغرض كالتالي :
1 |
$car = new Car(); |
لاحقا وبعد مرور القليل من الوقت, تتغير المعطيات ويتقدم البرنامج حيث أنه بدل صف واحد للسيارة قد ينتج لدنيا عدة صفوف , صف لكل نوع سيارة. وقد نحتاج للمرور بكافة الأماكن التي انشئنا فيها الأغراض وتعديلها للصف الجديد الذي هو نوع السيارة.
الحل الأمثل هو عدم إنشاء الأغراض بالطريقة السابقة, وإنما استخدام نمط المصنع للتكفل بإنشاء الاغراض بالطريقة المناسبة.
الحل:
في القسم السابق تحدثنا عن إنشاء أغراض لصف السيارة بإستخدام المصطلح new
. ومن ثم واجهنا مشكلة تعدد الصفوف حسب نوع السيارة متل Sedan, SUV إلخ..
لحل المشكلة بالشكل الأمثل قررنا أنه يجب استخدام نمط المصنع لحمل مسؤولية إنشاء الأغراض مهما اختلف شكلها, ومن ثم إستدعاء الميثود الساكنة في المصنع لإنشاء الأغراض.
1 |
<?php
|
2 |
|
3 |
class carFactory { |
4 |
|
5 |
public function __construct() { |
6 |
// ... //
|
7 |
}
|
8 |
|
9 |
public static function build ($type = '') { |
10 |
|
11 |
if($type == '') { |
12 |
throw new Exception('Invalid Car Type.'); |
13 |
} else { |
14 |
|
15 |
$className = 'car_'.ucfirst($type); |
16 |
|
17 |
// Assuming Class files are already loaded using autoload concept
|
18 |
if(class_exists($className)) { |
19 |
return new $className(); |
20 |
} else { |
21 |
throw new Exception('Car type not found.'); |
22 |
}
|
23 |
}
|
24 |
}
|
25 |
}
|
في الكود السابق , هنالك ميثود ساكنة Static واحدة مسؤولة عن إستدعاء الصف المناسب وإنشاء الغرض حسب النوع المدخل للمتحول. الآن كل مانحتاجه هي صفوف متزامنة لأنواع السيارات:
1 |
<?php
|
2 |
|
3 |
class car_Sedan { |
4 |
|
5 |
public function __construct() { |
6 |
echo "Creating Sedan"; |
7 |
}
|
8 |
|
9 |
}
|
10 |
|
11 |
class car_Suv { |
12 |
|
13 |
public function __construct() { |
14 |
echo "Creating SUV"; |
15 |
}
|
16 |
|
17 |
}
|
حتى الآن لدينا هذه الصفوف والميثود الخاصة بنمط تصميم المصنع . كل مانحتاجه هو التدريب على كيفية طلب الميثود وإنشاء أغراض جديدة حتى نكون جاهزين . على سبيل المثال:
1 |
// Creating new Sedan
|
2 |
$sedan = carFactory::build('sedan'); |
3 |
|
4 |
// Creating new SUV
|
5 |
$suv = carFactory::build('suv'); |
إضافة صف جديد:
إضافة صفوف جديدة هو أمر سهل جدا ولايحتاج اي تغيير في نمط المصنع, كل ماعليك هو إنشاء الصف المناسب وهو جاهز للإستخدام:
1 |
<?php
|
2 |
class car_Luxury { |
3 |
|
4 |
public function __construct() { |
5 |
echo "Creating Luxury"; |
6 |
}
|
7 |
|
8 |
}
|
9 |
|
10 |
// Creating new Luxury
|
11 |
$luxury = carFactory::build('luxury'); |
النتيجة :
عند التفكير بأسلوب أنماط التصاميم, تعتبر فكرة إنشاء أغراض بإستخدام كلمة new
فكرة سيئة جداَ. نمط المصنع يحل هذه المشكلة بكونه مكان مركزي لإنشاء الأغراض المطلوبة.