المنشئات المصنعية
جزء من قسم البرمجة كائنية التوجه في رحلة Dart على Coddy. الدرس 14 من 110.
إن factory constructor هو constructor خاص لا ينشئ دائمًا instance جديدة. وعلى خلاف constructors العادية، يمكن لـ factory constructor أن يعيد instance موجودة، أو subtype، أو حتى 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 دائمًا نفس الـ instance. وبغضّ النظر عن عدد مرات إجراء Logger()، ستحصل على الكائن identical. يُستخدم هذا النمط عادةً لتنفيذ النماذج الفردية.
تختلف Factory constructors عن المُنشئات العادية بطريقة أساسية: فهي لا تملك صلاحية الوصول إلى this لأنها قد لا تُنشئ instance جديدة على الإطلاق. وبدلًا من ذلك، يجب أن تُعيد كائنًا بشكل صريح:
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 مفيدة عندما تحتاج إلى التحكم في إنشاء instance، مثل إرجاع كائنات مخزّنة مؤقتًا، أو تنفيذ تجمعات الكائنات، أو تحديد النوع الفرعي الذي يجب إنشاءه بناءً على معلمات الإدخال.
التحدي
سهللننشئ نظام إشعارات يستخدم مُنشئات المصنع لإنشاء أنواع مختلفة من الإشعارات استنادًا إلى إدخال نصي بسيط.
ستنشئ ملفين لتنظيم التعليمات البرمجية الخاصة بك:
notification.dart: عرّف فئةNotificationالتي تعمل كـ base لجميع أنواع الإشعارات. يجب أن تحتوي فئتك على:- حقل
String message - مُنشئ named خاص
Notification._internalيقوم بتهيئة message - مُنشئ factory
Notification(String type, String message)يعيد أنواعًا فرعية مختلفة من الإشعارات استنادًا إلى المعاملtype:- إذا كان type هو
'email'، فأعدEmailNotification - إذا كان type هو
'sms'، فأعدSMSNotification - otherwise، أعد
PushNotification
- إذا كان type هو
- أسلوب
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: استورد فئة الإشعارات وأنشئ ثلاثة إشعارات باستخدام مُنشئ factory:- إشعار Email برسالة
'Welcome!' - إشعار SMS برسالة
'Your code is 1234' - إشعار Push برسالة
'New update available'
send()على كل إشعار بالترتيب المذكور أعلاه.- إشعار Email برسالة
الناتج المتوقع:
Email: Welcome!
SMS: Your code is 1234
Push: New update availableجرّب بنفسك
import 'notification.dart';
void main() {
// TODO: أنشئ إشعار بريد إلكتروني بالرسالة 'Welcome!'
// TODO: Create an SMS notification with message 'Your code is 1234'
// TODO: Create a push notification with message 'New update available'
// TODO: استدعِ send() على كل إشعار بالترتيب
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات الـ OOP
الملفات الخارجيةالمكتبات والـ Importsمقدمة في الـ OOPالـ Classes مقابل الـ Objectsالكلمة المفتاحية thisالـ Methodsمتغيرات الـ Instanceأساسيات الـ Constructorمراجعة - آلة حاسبة بسيطة4أمان الـ Null
مقدمة في أمان الـ NullNullable مقابل Non-Nullableعاملا الـ ? و !الكلمة المفتاحية Late وأمان الـ Nullالعوامل المدركة للـ Nullأمان الـ Null في الـ Classesمراجعة - نظام ملف تعريف المستخدم7الفئات المجردة والواجهات
الفئات المجردةالدوال المجردةالواجهات في Dartالواجهات الضمنيةالتنفيذ مقابل التوسيعالواجهات المتعددةمراجعة - حاسبة الأشكال10المجموعات والأنماط العامة
نظرة عامة على List و Set و Mapالمجموعات آمنة النوعالفئات العامةالدوال العامةقيود الأنماط العامةIterable و Iteratorملخص - التخزين العام13مفاهيم OOP المتقدمة
التركيب مقابل الوراثة (Composition vs Inheritance)دوال التوسعة (Extension Methods)الأصناف القابلة للاستدعاء (Callable Classes)الأصناف المختومة (Sealed Classes - Dart 3)السجلات (Records - Dart 3)الأنماط والمطابقة (Patterns & Matching - 3.0)التعدادات مع الدوال (Enums with Methods)2المنشئات في Dart
المنشئ الافتراضيالمنشئات المسماةقوائم التهيئةالمنشئات الثابتةالمنشئات المصنعيةالمنشئات الموجهةملخص - بناء الأشكال5التغليف (Encapsulation)
الأعضاء العامة مقابل الخاصةاتفاقية البادئة _الخصوصية على مستوى المكتبةتعمق في Getters و Settersإخفاء المعلوماتمراجعة - سجلات الطلاب8Mixins
مقدمة إلى Mixinsإنشاء Mixinsاستخدام Mixins متعددةالكلمة المفتاحية on في MixinsMixin مقابل الوراثة (Inheritance)Mixin مقابل الواجهة (Interface)مراجعة - نظام الحيوانات (Animal System)3خصائص الـ Class
أعضاء الـ Instance مقابل الـ Staticحقول Final و Constمتغيرات Lateالـ Static Methods والحقولدوال الـ Getters والـ Settersمراجعة - مدير الحساب البنكي6الوراثة
أساسيات الوراثةالكلمة المفتاحية superإعادة تعريف الدوال (Method Overriding)الوسم @overrideالكلمة المفتاحية final Classالدوال البانية والوراثةمراجعة - هيكلية الموظفين9تعدد الأشكال
أساسيات تعدد الأشكالتعدد الأشكال عبر الـ Interfacesالتحقق من النوع أثناء التشغيلالمعاملات is و asالكلمة المفتاحية Covariantملخص - معالج الدفع12البرمجة الكائنية غير المتزامنة (Async OOP)
Futures و async/awaitأساسيات الـ Streamsمتحكمات الـ Streamsالـ Constructors غير المتزامنةالعمليات غير المتزامنة في دوال الكلاسمراجعة - جالب البيانات (Data Fetcher)15أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط طريقة القالبنمط الحالةنمط التركيبنمط المستودعتدرّب بنفسك: مترجم Dart عبر الإنترنت