OOP mixin In dart

🔷 ما هو الـ Mixin؟
✅ التعريف الرسمي:

Mixin هو طريقة لإعادة استخدام كود في عدة كلاسات مختلفة بدون الحاجة للوراثة التقليدية (extends)، ويُستخدم عندما نريد دمج سلوك (behavior) في كلاس دون جعله جزءًا من سلسلة الوراثة.

✅ الشكل العام:
mixin MixinName {
  // خصائص أو دوال قابلة لإعادة الاستخدام
}
Dart
🎯 الهدف من mixin:
  • إعادة استخدام الكود دون الاعتماد على الوراثة.
  • تحقيق “الوراثة الأفقية” بدل “الوراثة العمودية”.
  • إعطاء الكلاسات وظائف إضافية بسهولة.
🧠 لماذا نستخدمه؟
المشكلةالحل بـ mixin
Dart لا تدعم الوراثة المتعددة (multiple inheritance)mixin تسمح بإضافة وظائف متعددة
تريد تشارك كود بين عدة كلاسات مختلفةاكتب السلوك مرة، وادمجه بكل كلاس بسهولة
// كلاس أساسي يحتوي الخصائص المشتركة
class Person {
  String name;

  Person(this.name);

  void showInfo() {
    print("الاسم: $name");
  }
}

// Mixin لإضافة سلوك التسجيل
mixin Logger {
  void log(String message) {
    print("LOG: $message");
  }
}

// Admin يرث من Person ويستخدم mixin Logger
class Admin extends Person with Logger {
  Admin(String name) : super(name);

  void deleteUser(String userName) {
    log("تم حذف المستخدم: $userName");
  }
}

// User يرث فقط من Person
class User extends Person {
  User(String name) : super(name);

  void browse() {
    print("$name يتصفح الموقع 📄");
  }
}

// برنامج التشغيل
void main() {
  Admin admin = Admin("أحمد المشرف");
  admin.showInfo();             // الاسم: أحمد المشرف
  admin.deleteUser("ياسين");   // LOG: تم حذف المستخدم: ياسين

  print('-----------------');

  User user = User("ياسين");
  user.showInfo();             // الاسم: ياسين
  user.browse();               // ياسين يتصفح الموقع 📄
}
Dart
✅ مثال 1: Mixin للصوت
mixin SoundMixin {
  void makeSound(String sound) {
    print("الصوت: $sound");
  }
}

class Dog with SoundMixin {
  void bark() {
    makeSound("هو هو 🐶");
  }
}

class Cat with SoundMixin {
  void meow() {
    makeSound("مياو 🐱");
  }
}

void main() {
  Dog dog = Dog();
  dog.bark(); // الصوت: هو هو 🐶

  Cat cat = Cat();
  cat.meow(); // الصوت: مياو 🐱
}
Dart
✅ شرح المثال:
  • SoundMixin يحتوي على دالة واحدة.
  • Dog و Cat استخدموا with SoundMixin ليحصلوا على الدالة.
  • كل واحد منهم استخدمها بطريقته، دون وراثة من نفس الكلاس.
✅ الفرق بين extends و with و implements
الكلمةمعناهاتستخدم مع
extendsوراثة من كلاس واحد فقطكلاس واحد
implementsتطبيق واجهة، يجب تنفيذ كل شيءواجهات
withدمج سلوك mixin1 أو أكثر من mixins
✅ خصائص الـ mixin في Dart:
الخاصيةالقيمة
✅ يمكن استخدامه مع أكثر من كلاس؟نعم
✅ يمكن استخدام أكثر من mixin؟نعم
❌ يحتوي على constructor؟لا
✅ يمكنه احتواء خصائص ودوال؟نعم
❌ يمكنه الوصول لـ super؟لا، إلا في mixin on
✅ يدعم التكرار وإعادة الاستخدام؟نعم جدًا
✅ مثال 2: Mixin للطباعة والتخزين
// كلاس أساسي يحتوي خصائص مشتركة
class Document {
  final String title;

  Document(this.title);

  void showTitle() {
    print("العنوان: $title");
  }
}

// mixin للطباعة
mixin Printable {
  void printInfo() {
    print("📄 طباعة البيانات...");
  }
}

// mixin للحفظ
mixin Saveable {
  void save() {
    print("💾 تم حفظ البيانات");
  }
}

// Report يرث من Document ويضيف سلوك من Printable و Saveable
class Report extends Document with Printable, Saveable {
  Report(String title) : super(title);

  void generate() {
    print("📊 توليد التقرير...");
  }
}

// التشغيل
void main() {
  Report report = Report("تقرير المبيعات");
  report.showTitle();    // العنوان: تقرير المبيعات
  report.generate();     // 📊 توليد التقرير...
  report.printInfo();    // 📄 طباعة البيانات...
  report.save();         // 💾 تم حفظ البيانات
}
Dart
✅ ملاحظة: ماذا يعني mixin on؟

mixin on تعني: هذا الـ mixin لا يمكن استخدامه إلا مع كلاس يورث من كلاس معين أو يحتوي خصائص محددة.

مثال:
class Vehicle {
  void move() => print("التحرك...");
}

mixin Electric on Vehicle {
  void charge() => print("الشحن...");
}

class Tesla extends Vehicle with Electric {}

void main() {
  Tesla t = Tesla();
  t.move();   // التحرك...
  t.charge(); // الشحن...
}
Dart

⛔ لو حاولت تستخدم Electric مع كلاس لا يورث من Vehicle → يعطيك خطأ.

✅ حالات استخدام mixin:
الحالةالمثال
إعادة استخدام دوال مساعدةمثل Logger, Validator
التعامل مع التخزين المؤقتCacheMixin, Saveable
وظائف متعددة لحالات مختلفةScrollable, Dragable, Clickable
أنظمة الألعابMovable, Shootable, Damageable
التطبيقاتNetworkHandler, ToastMessage, ThemeManager
✅ خلاصة الفرق بين abstract, interface, mixin
العنصرabstract classinterfacemixin
يحتوي منطق؟
يحتوي خصائص؟
يمكنه أن يحتوي constructor؟
يدعم الوراثة؟✅ (واحد فقط)
يدعم الاستخدام مع أكثر من كلاس؟
يجبر على التنفيذ؟❌ جزئي✅ كلي❌ لا
✅ خلاصة شاملة جدًا:
  • mixin = طريقة ذكية لإضافة وظائف جاهزة إلى كلاس بدون وراثة.
  • مناسب عندما تريد دمج دوال مساعدة في أكثر من كلاس.
  • لا يمكنه أن يحتوي على constructor.
  • يمكن استخدام أكثر من mixin مع كلاس واحد.
  • لا يُستخدم كـ “قالب” مثل abstract class ولا كـ “عقد” مثل interface.