🎯 سلسلة دروس Dart: لغة البرمجة من الصفر إلى الاحتراف
مرحباً بكم في هذا الدليل الشامل والمفصل باللغة العربية لتعلم لغة البرمجة Dart. يشتمل هذا الدليل على أمثلة عملية ومشاريع تطبيقية تأخذك خطوة بخطوة من البداية وحتى الاحتراف.
كتاب الدورة الشامل بصيغة PDF وجاهز للطباعة
يمكنك تحميل المذكرة البرمجية الكاملة والمجهزة لهذه الدروس بدقة متناهية من خلال نسخة الملف الأصلي المنظم.
📌 محتويات السلسلة:
- ✅ أساسيات Dart — المتغيرات والأنواع
- ✅ التحكم في التدفق (if / for / while)
- ✅ الدوال والمعاملات (Functions)
- ✅ البرمجة كائنية التوجه (OOP)
- ✅ القوائم والخرائط والمجموعات
- ✅ البرمجة غير المتزامنة (async / await)
- ✅ معالجة الأخطاء (Exception Handling)
- ✅ الدوال المجهولة والـ Closures
- ✅ الـ Mixins والـ Extensions
- ✅ مشروع تطبيقي متكامل
الدرس الأول: مقدمة إلى Dart
1.1 ما هي Dart؟
Dart هي لغة برمجة متعددة الأغراض طورتها شركة Google عام 2011. تُستخدم بشكل رئيسي لبناء تطبيقات Flutter للموبايل والويب وسطح المكتب، لكنها أيضاً قادرة على بناء تطبيقات سيرفر وسكريبتات. تجمع Dart بين سهولة Python وأداء C++، مع دعم كامل للبرمجة كائنية التوجه والبرمجة غير المتزامنة.
| الخاصية | التفاصيل |
|---|---|
| المطور | |
| سنة الإصدار | 2011 |
| نمط البرمجة | كائنية التوجه + وظيفية |
| التحويل | JIT (تطوير) + AOT (إنتاج) |
| الاستخدامات | Flutter, Web, Server, CLI |
| الموقع الرسمي | dart.dev |
1.2 تثبيت Dart
يمكن تثبيت Dart بعدة طرق تختلف باختلاف نظام التشغيل:
- Windows: تنزيل الـ SDK من dart.dev/get-dart أو عبر Chocolatey باستخدام الأمر:
choco install dart-sdk - macOS: عبر Homebrew باستخدام الأمر:
brew install dart - Linux: عبر apt باستخدام الأمر:
sudo apt install dart - أسهل طريقة: تثبيت Flutter يتضمن Dart تلقائياً
1.3 أول برنامج بـ Dart
إليك الهيكل البرمجي القياسي لكتابة برنامجك الأول:
// أول برنامج Dart
void main() {
print('مرحباً بالعالم!');
print('Hello, Dart!');
}
// تشغيل البرنامج عبر الطرفية:
// dart run main.dart
main() — هي نقطة الدخول الإلزامية للبرنامج.
الدرس الثاني: المتغيرات وأنواع البيانات
2.1 تعريف المتغيرات
في Dart يمكن تعريف المتغيرات بثلاث طرق أساسية:
void main() {
// 1. var — يستنتج النوع تلقائياً
var name = 'أحمد';
var age = 25;
var gpa = 3.85;
// 2. التصريح الصريح بالنوع
String city = 'الجزائر';
int year = 2024;
double weight = 70.5;
bool isStudent = true;
// 3. dynamic — يقبل أي نوع (تجنبه إذا أمكن)
dynamic anything = 'نص';
anything = 42; // مسموح!
print('الاسم: $name، العمر: $age');
}
2.2 أنواع البيانات الأساسية
| النوع | الوصف | مثال |
|---|---|---|
int |
عدد صحيح بأي حجم | int x = 42; |
double |
عدد عشري | double d = 3.14; |
num |
int أو double | num n = 10; |
String |
نص (Unicode كامل) | String s = 'مرحباً'; |
bool |
قيمة منطقية | bool b = true; |
List |
قائمة مرتبة | List<int> l = [1,2,3]; |
Map |
قاموس مفتاح/قيمة | Map<String,int> m = {}; |
Set |
مجموعة بدون تكرار | Set<String> s = {}; |
2.3 الثوابت (const و final)
void main() {
// final: يُحدد مرة واحدة عند التشغيل
final String username = 'admin';
final DateTime now = DateTime.now();
// const: ثابت وقت الترجمة (compile-time)
const double pi = 3.14159;
const int max = 100;
print('PI = $pi');
print('تسجيل الدخول: $username');
}
| الكلمة | وقت التحديد | متى تستخدمه؟ |
|---|---|---|
final |
وقت التشغيل (runtime) | القيم المحسوبة أثناء التشغيل |
const |
وقت الترجمة (compile-time) | القيم المعروفة مسبقاً |
2.4 Null Safety في Dart
إحدى أهم ميزات Dart الحديثة هي Null Safety — وهي ضمان عدم حدوث أخطاء NullPointerException:
void main() {
// بدون ? : لا يمكن أن يكون null
String name = 'أحمد';
// مع ? : يمكن أن يكون null
String? nickname = null;
nickname = 'أبو أحمد';
// ?? : قيمة بديلة إذا كان null
String display = nickname ?? 'بدون لقب';
// ?. : الوصول الآمن
int? length = nickname?.length;
// ! : أنا متأكد أنه ليس null
int len = nickname!.length;
print('الاسم: $name');
print('اللقب: $display');
print('الطول: $length');
}
String? عندما تتوقع قيمة فارغة محتملة.
الدرس الثالث: العمليات والتعبيرات
3.1 العمليات الحسابية
import 'dart:math';
void main() {
int a = 10, b = 3;
print(a + b); // 13 — جمع
print(a - b); // 7 — طرح
print(a * b); // 30 — ضرب
print(a / b); // 3.333... — قسمة عشرية
print(a ~/ b); // 3 — قسمة صحيحة
print(a % b); // 1 — باقي القسمة
print(pow(2, 8)); // 256
print(sqrt(16)); // 4.0
}
3.2 عمليات المقارنة والمنطق
void main() {
int x = 5, y = 10;
// مقارنة
print(x == y); // false
print(x != y); // true
print(x < y); // true
print(x >= y); // false
// منطق
bool a = true, b = false;
print(a && b); // false (AND)
print(a || b); // true (OR)
print(!a); // false (NOT)
// مشغّل التعيين المختصر
int count = 0;
count += 5; // count = count + 5
count *= 2; // count = count * 2
count++; // count = count + 1
print(count); // 12
}
3.3 String Interpolation والعمليات النصية
void main() {
String first = 'محمد';
String last = 'أمين';
int age = 22;
// الإدراج في النص
print('الاسم: $first $last');
print('العمر: ${age + 1} السنة القادمة');
// عمليات على النصوص
String s = ' مرحبا بالعالم ';
print(s.trim()); // إزالة المسافات
print(s.toUpperCase()); // أحرف كبيرة
print(s.toLowerCase()); // أحرف صغيرة
print(s.contains('عالم')); // true
print(s.replaceAll('مرحبا', 'أهلاً'));
print(s.split(' ')); // قائمة كلمات
print('Dart'.length); // 4
print('hello'[0]); // h
// نص متعدد الأسطر
String multiLine = '''
السطر الأول
السطر الثاني
السطر الثالث
''';
print(multiLine);
}
الدرس الرابع: التحكم في التدفق
4.1 الجملة الشرطية if / else
void main() {
int grade = 75;
if (grade >= 90) {
print('ممتاز');
} else if (grade >= 80) {
print('جيد جداً');
} else if (grade >= 70) {
print('جيد');
} else if (grade >= 60) {
print('مقبول');
} else {
print('راسب');
}
// الصيغة المختصرة (Ternary)
String result = grade >= 60 ? 'ناجح' : 'راسب';
print(result);
// if كتعبير (Dart 3+)
var msg = if (grade >= 60) 'ناجح' else 'راسب';
}
4.2 Switch / Pattern Matching
void main() {
String day = 'الإثنين';
switch (day) {
case 'السبت':
case 'الأحد':
print('عطلة نهاية الأسبوع');
break;
case 'الإثنين':
case 'الثلاثاء':
case 'الأربعاء':
case 'الخميس':
case 'الجمعة':
print('يوم عمل');
break;
default:
print('يوم غير معروف');
}
// switch expression (Dart 3)
int score = 85;
String letter = switch (score) {
>= 90 => 'A',
>= 80 => 'B',
>= 70 => 'C',
>= 60 => 'D',
_ => 'F',
};
print('التقدير: $letter');
}
4.3 حلقات التكرار
void main() {
// for التقليدي
for (int i = 0; i < 5; i++) {
print('التكرار رقم $i');
}
// for-in
List<String> fruits = ['تفاح', 'موز', 'برتقال'];
for (String fruit in fruits) {
print('الفاكهة: $fruit');
}
// forEach مع دالة مجهولة
fruits.forEach((f) => print('🍎 $f'));
// while
int count = 0;
while (count < 3) {
print('العدد: $count');
count++;
}
// do-while
int n = 0;
do {
print('do-while: $n');
n++;
} while (n < 3);
// break و continue
for (int i = 0; i < 10; i++) {
if (i == 3) continue;
if (i == 7) break;
print(i);
}
}
الدرس الخامس: الدوال (Functions)
5.1 تعريف الدوال
void greet(String name) {
print('أهلاً يا $name!');
}
int add(int a, int b) {
return a + b;
}
double square(double x) => x * x;
String fullName(String f, String l) => '$f $l';
void main() {
greet('أحمد');
print(add(3, 7)); // 10
print(square(4.0)); // 16.0
print(fullName('محمد', 'أمين'));
}
5.2 المعاملات الاختيارية والمسماة
void createUser({
required String name,
int age = 18,
String? email,
}) {
print('الاسم: $name، العمر: $age');
if (email != null) print('الإيميل: $email');
}
String greetUser(String name, [String title = 'السيد']) {
return '$title $name';
}
void main() {
createUser(name: 'أحمد', age: 25, email: 'a@email.com');
createUser(name: 'سارة');
print(greetUser('محمد'));
print(greetUser('نورة', 'الآنسة'));
}
5.3 الدوال من الدرجة الأولى (First-Class Functions)
void main() {
var multiply = (int a, int b) => a * b;
print(multiply(3, 4)); // 12
List<int> numbers = [1, 2, 3, 4, 5];
var doubled = numbers.map((n) => n * 2).toList();
print(doubled);
var evens = numbers.where((n) => n % 2 == 0).toList();
print(evens);
var sum = numbers.reduce((acc, n) => acc + n);
print(sum);
// Closure
Function makeCounter() {
int count = 0;
return () => ++count;
}
var counter = makeCounter();
print(counter()); // 1
print(counter()); // 2
print(counter()); // 3
}
الدرس السادس: القوائم والمجموعات
6.1 List (القائمة)
void main() {
List<String> names = ['أحمد', 'سارة', 'خالد'];
var numbers = <int>[1, 2, 3, 4, 5];
print(names[0]); // أحمد
print(names.first); // أحمد
print(names.last); // خالد
names.add('فاطمة');
names.addAll(['يوسف', 'مريم']);
names.remove('سارة');
names.removeAt(0);
print(names.contains('خالد'));
numbers.sort();
numbers.sort((a, b) => b.compareTo(a));
var upperNames = names.map((n) => n.toUpperCase()).toList();
var longNames = names.where((n) => n.length > 3).toList();
var total = numbers.fold(0, (sum, n) => sum + n);
print('المجموع: $total');
var list1 = [1, 2, 3];
var list2 = [4, 5, 6];
var merged = [...list1, ...list2, 7];
print(merged);
}
6.2 Map (القاموس)
void main() {
Map<String, int> scores = {
'أحمد': 85,
'سارة': 92,
'خالد': 78,
};
print(scores['أحمد']);
scores['فاطمة'] = 95;
scores['أحمد'] = 88;
scores.remove('خالد');
print(scores.containsKey('سارة'));
scores.forEach((name, score) {
print('$name حصل على $score درجة');
});
int grade = scores['يوسف'] ?? 0;
print('درجة يوسف: $grade');
}
6.3 Set (المجموعة)
void main() {
Set<String> fruits = {'تفاح', 'موز', 'برتقال'};
fruits.add('تفاح');
fruits.add('عنب');
print(fruits.length); // 4
Set<int> a = {1, 2, 3, 4};
Set<int> b = {3, 4, 5, 6};
print(a.union(b));
print(a.intersection(b));
print(a.difference(b));
}
الدرس السابع: البرمجة كائنية التوجه (OOP)
7.1 الكلاسات (Classes)
class Student {
String name;
int age;
double grade;
Student(this.name, this.age, this.grade);
Student.guest() : name = 'زائر', age = 0, grade = 0;
String get letterGrade {
if (grade >= 90) return 'A';
if (grade >= 80) return 'B';
if (grade >= 70) return 'C';
return 'F';
}
set studentGrade(double g) {
if (g >= 0 && g <= 100) grade = g;
}
String introduce() {
return 'أنا $name، عمري $age، درجتي $grade ($letterGrade)';
}
@override
String toString() => 'Student($name, $age, $grade)';
}
void main() {
var s1 = Student('أحمد', 20, 88.5);
var s2 = Student.guest();
print(s1.introduce());
print(s2);
}
7.2 الوراثة (Inheritance)
class Person {
String name;
int age;
Person(this.name, this.age);
void introduce() {
print('اسمي $name وعمري $age');
}
}
class Student extends Person {
double gpa;
Student(super.name, super.age, this.gpa);
@override
void introduce() {
super.introduce();
print('معدلي: $gpa');
}
}
class Teacher extends Person {
String subject;
Teacher(super.name, super.age, this.subject);
@override
void introduce() {
super.introduce();
print('أدرّس مادة: $subject');
}
}
void main() {
var student = Student('أحمد', 20, 3.8);
var teacher = Teacher('سعاد', 40, 'الرياضيات');
student.introduce();
teacher.introduce();
}
7.3 الواجهات والـ Abstract
abstract class Shape {
double get area;
double get perimeter;
void describe() {
print('المساحة: ${area.toStringAsFixed(2)}');
}
}
class Circle extends Shape {
double radius;
Circle(this.radius);
@override
double get area => 3.14159 * radius * radius;
@override
double get perimeter => 2 * 3.14159 * radius;
}
class Rectangle extends Shape {
double width, height;
Rectangle(this.width, this.height);
@override
double get area => width * height;
@override
double get perimeter => 2 * (width + height);
}
class Drawable {
void draw() => print('رسم الشكل...');
}
class Square extends Shape implements Drawable {
double side;
Square(this.side);
@override double get area => side * side;
@override double get perimeter => 4 * side;
@override void draw() => print('رسم مربع بضلع $side');
}
void main() {
var c = Circle(5);
var r = Rectangle(4, 6);
var s = Square(3);
c.describe();
r.describe();
s.draw();
}
7.4 Mixins
mixin Flyable {
void fly() => print('$runtimeType يطير!');
int get altitude => 1000;
}
mixin Swimmable {
void swim() => print('$runtimeType يسبح!');
}
class Animal {
String name;
Animal(this.name);
}
class Duck extends Animal with Flyable, Swimmable {
Duck(super.name);
}
class Eagle extends Animal with Flyable {
Eagle(super.name);
}
void main() {
var duck = Duck('بطة');
var eagle = Eagle('نسر');
duck.fly();
duck.swim();
eagle.fly();
}
الدرس الثامن: البرمجة غير المتزامنة
8.1 Future — الوعود
البرمجة غير المتزامنة تُتيح لبرنامجك الاستمرار في العمل أثناء انتظار عمليات بطيئة مثل تحميل البيانات من الإنترنت أو قراءة الملفات.
import 'dart:async';
Future<String> fetchUserData() async {
await Future.delayed(Duration(seconds: 2));
return 'بيانات المستخدم: أحمد، 25 سنة';
}
Future<int> fetchScore(String userId) async {
await Future.delayed(Duration(seconds: 1));
return 95;
}
void main() async {
print('بدء التحميل...');
String data = await fetchUserData();
print(data);
int score = await fetchScore('user_1');
print('الدرجة: $score');
print('انتهى التحميل!');
}
8.2 معالجة الأخطاء في async
Future<String> riskyOperation() async {
await Future.delayed(Duration(seconds: 1));
throw Exception('خطأ في الشبكة!');
}
void main() async {
try {
String result = await riskyOperation();
print(result);
} catch (e) {
print('حدث خطأ: $e');
} finally {
print('انتهت العملية دائماً');
}
}
8.3 Stream — تدفق البيانات
import 'dart:async';
Stream<int> countDown(int from) async* {
for (int i = from; i >= 0; i--) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
}
void main() async {
await for (int count in countDown(3)) {
print(count == 0 ? 'انطلق! 🚀' : count);
}
}
الدرس التاسع: معالجة الأخطاء والاستثناءات
9.1 أنواع الأخطاء في Dart
| النوع | المعنى | مثال |
|---|---|---|
Error |
خطأ منطقي في البرنامج | قسمة على صفر |
Exception |
حالة استثنائية متوقعة | خطأ في الشبكة |
Custom Exception |
استثناء مخصص ومصمم من المبرمج | تنسيق خاطئ |
class InvalidAgeException implements Exception {
final String message;
InvalidAgeException(this.message);
@override
String toString() => 'InvalidAgeException: $message';
}
int validateAge(int age) {
if (age < 0 || age > 150) {
throw InvalidAgeException('العمر $age غير صحيح!');
}
return age;
}
void main() {
try {
validateAge(-5);
} on InvalidAgeException catch (e) {
print('خطأ مخصص: $e');
} catch (e) {
print('خطأ غير متوقع: $e');
} finally {
print('هذا يُنفَّذ دائماً');
}
}
الدرس العاشر: الميزات المتقدمة
10.1 Generics — الأنواع العامة
class Box<T> {
T value;
Box(this.value);
T getValue() => value;
void setValue(T newValue) => value = newValue;
@override
String toString() => 'Box<${T}>(value: $value)';
}
T getFirst<T>(List<T> list) => list.first;
void main() {
var intBox = Box<int>(42);
var stringBox = Box<String>('مرحباً');
print(intBox);
print(stringBox);
}
10.2 Extensions — توسعة الكلاسات
extension StringExtensions on String {
bool get isEmail => contains('@') && contains('.');
String capitalize() => isEmpty ? '' : this[0].toUpperCase() + substring(1);
}
void main() {
print('hello'.capitalize()); // Hello
print('a@b.com'.isEmail); // true
}
10.3 Records (Dart 3.0+)
void main() {
var point = (10.0, 20.0);
print(point.$1);
var student = (name: 'أحمد', age: 20, gpa: 3.8);
print(student.name);
(String, int) getUser() => ('سارة', 22);
var (name, age) = getUser();
print('$name: $age سنة');
}
الدرس الحادي عشر: مكتبات Dart الأساسية
11.1 dart:math
import 'dart:math';
void main() {
print(pi);
print(sqrt(144)); // 12.0
print(pow(2, 10)); // 1024
var rng = Random();
print(rng.nextInt(100));
}
11.2 dart:convert
import 'dart:convert';
void main() {
Map<String, dynamic> student = {
'name': 'أحمد',
'age': 20,
'isActive': true,
};
String jsonString = jsonEncode(student);
print(jsonString);
String raw = '{"city":"الجزائر","pop":3000000}';
Map<String, dynamic> data = jsonDecode(raw);
print(data['city']);
}
الدرس الثاني عشر: مشروع تطبيقي — نظام إدارة مهام
12.1 هيكل وبناء المشروع
أولاً: كلاس الكائن أو النموذج (Task Model)
enum Priority { low, medium, high }
class Task {
final int id;
String title;
String description;
bool isDone;
Priority priority;
final DateTime createdAt;
DateTime? completedAt;
Task({
required this.id,
required this.title,
this.description = '',
this.isDone = false,
this.priority = Priority.medium,
}) : createdAt = DateTime.now();
void complete() {
isDone = true;
completedAt = DateTime.now();
}
@override
String toString() =>
'[${isDone ? ' ✓ ' : ' '}] $title (${priority.name})';
}
ثانياً: كلاس المدير والمتحكم بالنظام (TaskManager)
class TaskManager {
final List<Task> _tasks = [];
int _nextId = 1;
Task addTask(String title, {
String description = '',
Priority priority = Priority.medium,
}) {
final task = Task(
id: _nextId++,
title: title,
description: description,
priority: priority,
);
_tasks.add(task);
return task;
}
bool completeTask(int id) {
final task = findById(id);
if (task == null) return false;
task.complete();
return true;
}
Task? findById(int id) =>
_tasks.where((t) => t.id == id).firstOrNull;
List<Task> get pendingTasks =>
_tasks.where((t) => !t.isDone).toList();
void printAll() {
if (_tasks.isEmpty) { print('لا توجد مهام'); return; }
_tasks.forEach(print);
}
}
ثالثاً: تشغيل وتجربة النظام (Main Execute)
void main() {
final manager = TaskManager();
manager.addTask('دراسة Dart',
description: 'إنهاء الفصول الخمسة الأولى',
priority: Priority.high,
);
manager.addTask('تمرين Flutter', priority: Priority.high);
manager.addTask('تمرين رياضي', priority: Priority.medium);
print('=== جميع المهام ===');
manager.printAll();
manager.completeTask(1);
print('\n=== المهام المعلقة ===');
manager.pendingTasks.forEach(print);
}
ملخص — أهم ميزات ولغة Dart في 10 نقاط أساسية
| المفهوم والتقنية | مثال وبناء برمجي سريع |
|---|---|
| المتغيرات والأنواع | var x = 42; String s = 'hi'; |
| Null Safety | String? name = null; name ?? 'افتراضي'; |
| التحكم في التدفق | if/else، switch، for، while |
| الدوال البرمجية | int add(int a, int b) => a + b; |
| OOP والوراثة | class Dog extends Animal {} |
| الميكسينز (Mixins) | mixin Flyable { void fly(){} } |
| البرمجة غير المتزامنة | Future<String> fetch() async {} |
هل تفضل القراءة والتعلم دون اتصال؟
حمّل المذكرة الدراسية المرجعية الكاملة لجميع هذه الدروس في ملف واحد منسق ومعد للمراجعة المستمرة.

