التعدادات مع الدوال (Enums with Methods)
جزء من قسم Object Oriented Programming في رحلة Dart على Coddy — الدرس 88 من 110.
في Dart، لا تُعد الـ enums مجرد قوائم بسيطة من الثوابت - بل يمكن أن تحتوي على حقول (fields)، ومنشئات (constructors)، ودوال (methods)، مما يجعلها فئات مصغرة (mini-classes) قوية. يُطلق على هذا اسم enhanced enums، وهي تتيح لك إرفاق سلوك وبيانات مباشرة بكل قيمة من قيم الـ enum.
enum Status {
pending('Waiting'),
approved('Accepted'),
rejected('Denied');
final String displayName;
const Status(this.displayName);
bool get isFinalized => this == approved || this == rejected;
}
void main() {
var status = Status.pending;
print(status.displayName); // Waiting
print(status.isFinalized); // false
print(Status.approved.isFinalized); // true
}تستدعي كل قيمة enum المنشئ (constructor) مع وسيطاتها المحددة. يجب أن يكون المنشئ const، ويجب أن تكون جميع الحقول final. يمكنك إضافة دوال جلب (getters) ووسائل (methods) تعمل مع بيانات الـ enum أو تقارنها بالقيم الأخرى.
يمكن للتعدادات المحسنة (Enhanced enums) أيضًا تنفيذ الواجهات، مما يمنحها مرونة أكبر:
enum Priority implements Comparable<Priority> {
low(1),
medium(2),
high(3);
final int level;
const Priority(this.level);
@override
int compareTo(Priority other) => level.compareTo(other.level);
}
void main() {
var tasks = [Priority.high, Priority.low, Priority.medium];
tasks.sort();
print(tasks); // [Priority.low, Priority.medium, Priority.high]
}تعد التعدادات المحسنة (Enhanced enums) مثالية عندما يكون لديك مجموعة ثابتة من القيم التي يحتاج كل منها إلى بيانات أو سلوكيات مرتبطة بها - مثل أكواد الحالة مع الرسائل، أو الأولويات مع المستويات، أو الاتجاهات مع الإحداثيات.
التحدي
سهللنقم ببناء نظام لإدارة المهام باستخدام التعدادات المحسنة (enhanced enums)! ستقوم بإنشاء enum يمثل فئات مهام مختلفة، لكل منها خصائصها وسلوكياتها الخاصة التي تساعد في تنظيم العمل وترتيب أولوياته.
ستقوم بتنظيم الكود الخاص بك في ملفين:
task_category.dart: قم بإنشاء enum محسن يسمىTaskCategoryيمثل أنواعًا مختلفة من المهام في المشروع. يجب أن تحتوي كل فئة على:- حقل
String labelلاسم مقروء بشريًا - حقل
int priority(حيث 1 هو أعلى أولوية، و 3 هو أدنى أولوية) - منشئ
constيقوم بتهيئة كلا الحقلين - أربع قيم enum:
bug(label: "Bug Fix"، priority: 1)، وfeature(label: "New Feature"، priority: 2)، وdocumentation(label: "Documentation"، priority: 3)، وtesting(label: "Testing"، priority: 2) - مسترجع (getter) باسم
isUrgentيعيدtrueإذا كانت الأولوية 1 - دالة
describe()تعيد سلسلة نصية بالتنسيق التالي:[label] (Priority: [priority])
Comparable<TaskCategory>بحيث يمكن فرز المهام حسب الأولوية (رقم الأولوية الأقل = يأتي أولاً).- حقل
main.dart: قم باستيراد enum فئة المهام واستعرض قدراته:- أنشئ قائمة تحتوي على جميع فئات المهام الأربع بهذا الترتيب:
feature،bug،documentation،testing - اطبع وصف كل فئة باستخدام دالة
describe()، كل منها في سطر منفصل - اطبع سطرًا فارغًا
- قم بفرز القائمة حسب الأولوية واطبع
After sorting by priority: - اطبع تسمية (label) كل فئة تم فرزها، كل منها في سطر منفصل
- اطبع سطرًا فارغًا
- اطبع
Urgent tasks: - قم بالمرور عبر الترتيب الأصلي (
feature،bug،documentation،testing) واطبع فقط تسميات الفئات التي يكون فيهاisUrgentصحيحًا (true)
- أنشئ قائمة تحتوي على جميع فئات المهام الأربع بهذا الترتيب:
يجمع هذا التحدي بين ميزات الـ enum المحسنة: الحقول، والمنشئات، والمسترجعات، والدوال، وتنفيذ الواجهات - وكلها تعمل معًا لإنشاء نظام مفيد لتصنيف المهام!
المخرجات المتوقعة:
New Feature (Priority: 2)
Bug Fix (Priority: 1)
Documentation (Priority: 3)
Testing (Priority: 2)
After sorting by priority:
Bug Fix
New Feature
Testing
Documentation
Urgent tasks:
Bug Fixورقة مرجعية
يمكن أن تحتوي التعدادات المحسنة (Enhanced enums) في Dart على حقول، ومنشئات (constructors)، ودوال (methods)، مما يجعلها فئات مصغرة قوية تربط السلوك والبيانات بكل قيمة من قيم التعداد.
تعداد محسن أساسي مع حقول ومنشئ:
enum Status {
pending('Waiting'),
approved('Accepted'),
rejected('Denied');
final String displayName;
const Status(this.displayName);
}المتطلبات الأساسية:
- يجب أن يكون المنشئ
const - يجب أن تكون جميع الحقول
final - كل قيمة من قيم التعداد تستدعي المنشئ بوسائط محددة
يمكن أن تتضمن التعدادات المحسنة دوال جلب (getters) ودوال (methods):
enum Status {
pending('Waiting'),
approved('Accepted'),
rejected('Denied');
final String displayName;
const Status(this.displayName);
bool get isFinalized => this == approved || this == rejected;
}يمكن للتعدادات المحسنة تنفيذ واجهات (interfaces) مثل Comparable:
enum Priority implements Comparable<Priority> {
low(1),
medium(2),
high(3);
final int level;
const Priority(this.level);
@override
int compareTo(Priority other) => level.compareTo(other.level);
}استخدم التعدادات المحسنة عندما يكون لديك مجموعة ثابتة من القيم التي تحتاج كل منها إلى بيانات أو سلوك مرتبط بها.
جرّب بنفسك
import 'task_category.dart';
void main() {
// TODO: قم بإنشاء قائمة تحتوي على جميع فئات المهام الأربع بهذا الترتيب:
// feature, bug, documentation, testing
// TODO: اطبع وصف كل فئة باستخدام ()describe، وصف واحد في كل سطر
// TODO: اطبع سطراً فارغاً
// TODO: قم بفرز القائمة حسب الأولوية (priority)
// TODO: "After sorting by priority:" اطبع
// TODO: اطبع تسمية (label) كل فئة تم فرزها، واحدة في كل سطر
// TODO: اطبع سطراً فارغاً
// TODO: "Urgent tasks:" اطبع
// TODO: قم بالمرور عبر الترتيب الأصلي (feature, bug, documentation, testing)
// واطبع فقط تسميات الفئات التي تكون فيها قيمة isUrgent هي true
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
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أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط طريقة القالبنمط الحالةنمط التركيبنمط المستودع