🏭 ما هو Factory Constructor
؟
✅ التعريف:
Factory Constructor
هو نوع خاص من الـ Constructor يُستخدم عندما تريد التحكم في إنشاء الكائن (object) ، بدلًا من إنشائه مباشرة دائمًا.
يعني: بدل ما new
تنشئ كل مرة كائن جديد، تقدر تقول:
“لا، إذا كان هذا الكائن موجود سابقًا، رجعه لي” أو “اعمل فحص قبل إنشاء الكائن” أو “رجع كائن مختلف تمامًا!”
✅ متى نستخدم factory
؟
السبب التوضيح ✅ عند إعادة استخدام كائن موجود (Singleton مثلاً) ما تنشئ كائن جديد ✅ عند تنفيذ منطق قبل الإنشاء (validation أو parsing) فحص القيم أولاً ✅ عند إرجاع كائن من نوع فرعي (subclass) ترجع كائن مختلف ✅ عند إرجاع قيمة غير تقليدية ترجع null أو شيء مخصص
✅ الشكل العام:
class ClassName {
factory ClassName () {
// منطق الإنشاء المخصص
return ...;
}
}
Dart
✅ مثال 1: فحص قبل الإنشاء
class User {
final String name;
User . _internal ( this .name); // private constructor
factory User ( String name) {
if (name.isEmpty) {
throw Exception ( "الاسم لا يمكن أن يكون فارغًا" );
}
return User . _internal (name);
}
}
void main () {
var user = User ( "Ali" ); // ✅ سليم
// var user2 = User(""); ❌ سيرمي Exception
}
Dart
✅ الشرح:
استخدمنا factory
لفحص الاسم قبل إنشاء الكائن.
إذا الاسم فاضي، نرمي Exception.
واستخدمنا constructor داخلي _internal
ليكون خاص ولا يُستخدم من الخارج.
✅ مثال 2: Singleton (كائن واحد فقط)
class Logger {
static final Logger _instance = Logger . _internal ();
Logger . _internal (); // private constructor
factory Logger () {
return _instance;
}
void log ( String message) {
print ( "LOG: $ message " );
}
}
void main () {
var l1 = Logger ();
var l2 = Logger ();
print ( identical (l1, l2)); // true ✅ نفس الكائن
}
Dart
✅ الشرح:
كل استدعاء لـ Logger()
يرجع نفس النسخة الوحيدة.
استخدمنا factory
لتحقيق نمط Singleton.
✅ مثال 3: تحويل JSON إلى كائن
class Product {
final String name;
final double price;
Product ( this .name, this .price);
factory Product . fromJson ( Map < String , dynamic > json) {
return Product (json[ 'name' ], json[ 'price' ]);
}
}
void main () {
var json = { 'name' : 'Keyboard' , 'price' : 199.99 };
var product = Product . fromJson (json);
print (product.name); // Keyboard
}
Dart
✅ الشرح:
استخدمنا factory
لتحويل JSON إلى كائن Product
.
مثالي للتعامل مع APIs.
🆚 الفرق بين factory
و constructor
العادي
المقارنة constructor
العاديfactory constructor
ينشئ كائن جديد دائمًا؟ ✅ نعم ❌ لا (اختياري) يرجع نفس الكلاس فقط؟ ✅ نعم ❌ ممكن يرجع subclass أو null يمكنه تنفيذ منطق قبل الإنشاء؟ ❌ لا ✅ نعم يمكنه إرجاع كائن موجود؟ ❌ لا ✅ نعم هل يمكن استخدام return
بداخله؟ ❌ لا ✅ نعم
✅ متى أستخدم factory
بدلاً من constructor عادي؟
الحالة استخدم factory
تريد تنفيذ شرط أو فحص ✅ تريد التحكم في منطق الإنشاء ✅ تريد cache أو singleton ✅ تريد إرجاع نوع مختلف ✅ تريد parsing من JSON ✅
✅ مثال 4: إرجاع نوع مختلف (SubClass)
abstract class Shape {
void draw ();
}
class Circle extends Shape {
@override
void draw () => print ( "رسم دائرة" );
}
class Square extends Shape {
@override
void draw () => print ( "رسم مربع" );
}
class ShapeFactory {
factory ShapeFactory ( String type) {
if (type == "circle" ) return Circle ();
if (type == "square" ) return Square ();
throw Exception ( "شكل غير معروف" );
}
}
void main () {
Shape s1 = ShapeFactory ( "circle" );
s1. draw (); // رسم دائرة
}
Dart
💡 خلاصة شاملة:
النقطة التوضيح factory
constructorيعطيك مرونة عالية في إنشاء الكائنات يمكنه إرجاع كائن جديد أو موجود ✅ يمكنه إرجاع نوع مختلف أو null ✅ مناسب لـ Singleton / JSON / فحص القيم ✅ لا يستخدم this
لإنشاء الكائن مباشرة ❌ بل يستخدم return