Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

المنشئات المصنعية

جزء من قسم Object Oriented Programming في رحلة Dart على Coddy — الدرس 14 من 110.

يُعد منشئ المصنع (factory constructor) منشئاً خاصاً لا يقوم دائماً بإنشاء مثيل جديد. وعلى عكس المنشئات العادية، يمكن لمنشئ المصنع إرجاع مثيل موجود بالفعل، أو نوع فرعي، أو حتى null (إذا كان يقبل القيمة null). يتم التصريح عنه باستخدام الكلمة المفتاحية factory.

class Logger {
  static final Logger _instance = Logger._internal();
  
  // منشئ مسمى خاص
  Logger._internal();
  
  // منشئ مصنع
  factory Logger() {
    return _instance;
  }
}

Logger log1 = Logger();
Logger log2 = Logger();
print(identical(log1, log2)); // true

في هذا المثال، يعيد منشئ المصنع (factory constructor) دائماً نفس المثيل. بغض النظر عن عدد المرات التي تستدعي فيها Logger()، ستحصل على الكائن المتطابق نفسه. يُستخدم هذا النمط بشكل شائع لتنفيذ الـ singletons.

تختلف منشئات المصنع (Factory constructors) عن المنشئات العادية بطريقة أساسية: فهي لا تملك حق الوصول إلى this لأنها قد لا تنشئ مثيلاً جديداً على الإطلاق. بدلاً من ذلك، يجب عليها إرجاع كائن بشكل صريح:

class Shape {
  factory Shape(String type) {
    if (type == 'circle') return Circle();
    if (type == 'square') return Square();
    return Rectangle();
  }
}

class Circle extends Shape { Circle() : super._(); }
class Square extends Shape { Square() : super._(); }
class Rectangle extends Shape { Rectangle() : super._(); }

تعد منشئات المصنع (Factory constructors) مفيدة عندما تحتاج إلى التحكم في عملية إنشاء الكائنات، مثل إرجاع الكائنات المخزنة مؤقتًا، أو تنفيذ تجمعات الكائنات (object pools)، أو تحديد النوع الفرعي الذي سيتم إنشاؤه بناءً على معلمات الإدخال.

challenge icon

التحدي

سهل

لنقم ببناء نظام إشعارات يستخدم منشئات المصنع (factory constructors) لإنشاء أنواع مختلفة من الإشعارات بناءً على مدخل نصي بسيط.

ستقوم بإنشاء ملفين لتنظيم الكود الخاص بك:

  • notification.dart: قم بتعريف فئة Notification التي تعمل كقاعدة لجميع أنواع الإشعارات. يجب أن تحتوي الفئة الخاصة بك على:
    • حقل String message
    • منشئ مسمى خاص Notification._internal يقوم بتهيئة الرسالة
    • منشئ مصنع Notification(String type, String message) يقوم بإرجاع أنواع فرعية مختلفة من الإشعارات بناءً على معامل type:
      • إذا كان النوع هو 'email'، فقم بإرجاع EmailNotification
      • إذا كان النوع هو 'sms'، فقم بإرجاع SMSNotification
      • خلاف ذلك، قم بإرجاع PushNotification
    • دالة send() تقوم بطباعة Sending: [message]

في نفس الملف، قم بإنشاء ثلاث فئات فرعية ترث من Notification:

  • EmailNotification: قم بعمل override للدالة send() لطباعة Email: [message]
  • SMSNotification: قم بعمل override للدالة send() لطباعة SMS: [message]
  • PushNotification: قم بعمل override للدالة send() لطباعة Push: [message]

تحتاج كل فئة فرعية إلى منشئ يأخذ message ويمررها إلى الفئة الأب باستخدام super._internal(message).

  • main.dart: قم باستيراد فئة الإشعارات الخاصة بك وإنشاء ثلاثة إشعارات باستخدام منشئ المصنع:
    • إشعار بريد إلكتروني برسالة 'Welcome!'
    • إشعار SMS برسالة 'Your code is 1234'
    • إشعار دفع (push notification) برسالة 'New update available'
    قم باستدعاء send() لكل إشعار بالترتيب المذكور أعلاه.

المخرجات المتوقعة:

Email: Welcome!
SMS: Your code is 1234
Push: New update available

ورقة مرجعية

يُعد مُنشئ المصنع (factory constructor) مُنشئاً خاصاً يتم التصريح عنه باستخدام الكلمة المفتاحية factory، وهو لا يقوم دائماً بإنشاء مثيل جديد. وبخلاف المُنشئات العادية، يمكنه إرجاع مثيل موجود بالفعل، أو نوع فرعي، أو null.

لا تملك مُنشئات المصنع وصولاً إلى this ويجب أن تُرجع كائناً بشكل صريح.

مثال على نمط Singleton:

class Logger {
  static final Logger _instance = Logger._internal();
  
  Logger._internal(); // Private named constructor
  
  factory Logger() {
    return _instance; // Always returns same instance
  }
}

Logger log1 = Logger();
Logger log2 = Logger();
print(identical(log1, log2)); // true

إرجاع أنواع فرعية مختلفة:

class Shape {
  factory Shape(String type) {
    if (type == 'circle') return Circle();
    if (type == 'square') return Square();
    return Rectangle();
  }
}

class Circle extends Shape { Circle() : super._(); }
class Square extends Shape { Square() : super._(); }
class Rectangle extends Shape { Rectangle() : super._(); }

تُعد مُنشئات المصنع مفيدة للتحكم في إنشاء المثيلات، مثل إرجاع الكائنات المخزنة مؤقتاً (cached objects)، أو تنفيذ تجمعات الكائنات (object pools)، أو تحديد النوع الفرعي الذي سيتم إنشاؤه بناءً على معلمات الإدخال.

جرّب بنفسك

import 'notification.dart';

void main() {
  // TODO: إنشاء إشعار بريد إلكتروني مع الرسالة 'Welcome!'
  
  // TODO: إنشاء إشعار SMS مع الرسالة 'Your code is 1234'
  
  // TODO: إنشاء إشعار دفع مع الرسالة 'New update available'
  
  // TODO: استدعاء send() لكل إشعار بالترتيب
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming