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

تنفيذ الـ Interfaces

جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 41 من 61.

الآن بعد أن فهمت ما هي الواجهة، وهي بنية تحتوي على مؤشرات دوال فقط، حان الوقت لإنشاء تطبيقات ملموسة تفي بهذا العقد.

تذكّر واجهة ILogger من الدرس السابق:

typedef void (*LogFunc)(const char* message);

typedef struct {
    LogFunc log;
} ILogger;

لتنفيذ هذه الواجهة، نكتب دوال فعلية تطابق توقيع LogFunc، ثم ننشئ مثيلات من ILogger مع تعيين تلك الدوال لها:

void console_log(const char* message) {
    printf("[CONSOLE] %s\n", message);
}

void file_log(const char* message) {
    printf("[FILE] %s\n", message);  // محاكاة إخراج الملف
}

ILogger create_console_logger() {
    ILogger logger = { console_log };
    return logger;
}

ILogger create_file_logger() {
    ILogger logger = { file_log };
    return logger;
}

تُرجع كل دالة "constructor" ILogger مع ربط function مختلفة بها. لا يحتاج الكود الذي يستخدم أدوات التسجيل هذه إلى معرفة أي تنفيذ تلقّاه:

void do_work(ILogger* logger) {
    logger->log("Starting work...");
    logger->log("Work complete!");
}

int main() {
    ILogger console = create_console_logger();
    ILogger file = create_file_logger();
    
    do_work(&console);  // يستخدم console_log
    do_work(&file);     // يستخدم file_log
    return 0;
}

الدالة do_work منفصلة تمامًا عن تنفيذ التسجيل. يمكنك تبديل أدوات التسجيل بحرية دون تغيير أي من المنطق الأساسي: تلك هي قوة البرمجة وفق واجهة.

challenge icon

التحدي

سهل

لنبنِ نظام INotifier يوضّح كيف يمكن لتطبيقات مختلفة تلبية عقد الواجهة نفسه. ستنشئ مُرسِلَي إشعارات ملموسين، EmailNotifier وSMSNotifier، يلتزمان كلاهما بواجهة مشتركة لكنهما ينتجان مخرجات مختلفة.

ستنظّم شفرتك عبر ثلاثة ملفات:

  • notifier.h: عرّف الواجهة هنا. أنشئ نوع مؤشر دالة يُسمّى NotifyFunc ويأخذ رسالة من نوع const char* ولا يعيد أي قيمة. ثم عرّف بنية INotifier التي تحتوي فقط على مؤشر دالة notify من هذا النوع. أعلن أيضًا عن دالتي constructor: create_email_notifier وcreate_sms_notifier، بحيث تعيد كل منهما قيمة من نوع INotifier.
  • notifier.c: نفّذ دوال الإشعارات الملموسة وconstructor هنا. أنشئ:
    • email_notify: تطبع الرسالة بالتنسيق: [EMAIL] message
    • sms_notify: تطبع الرسالة بالتنسيق: [SMS] message
    • create_email_notifier: تعيد قيمة INotifier موصولة بـ email_notify
    • create_sms_notifier: تعيد قيمة INotifier موصولة بـ sms_notify
  • main.c: اجمع كل شيء هنا. اقرأ نوع الإشعار ورسالة، وأنشئ مُرسِل الإشعارات المناسب باستخدام دوال constructor، ثم أرسل الإشعار من خلال الواجهة.

سيستقبل برنامجك مُدخلين: نوع الإشعار (1 للبريد الإلكتروني، و2 للرسائل النصية SMS) ورسالة لإرسالها.

استخدم دوال constructor لإنشاء مُرسِل الإشعارات المناسب، ثم استدعِ notify من خلال الواجهة لعرض الرسالة.

مثال على المخرجات عندما يكون النوع 1 والرسالة Meeting at 3pm:

[EMAIL] Meeting at 3pm

مثال على المخرجات عندما يكون النوع 2 والرسالة Your code shipped:

[SMS] Your code shipped

تكمن قوة هذا النمط في أن main.c لا يحتاج إلى معرفة كيفية عمل كل مُرسِل إشعارات داخليًا. فهو يستدعي ببساطة دالة الواجهة notify، ثم يُنفَّذ التطبيق الصحيح. تذكّر استخدام حواجز include في ملف الرأس.

جرّب بنفسك

#include <stdio.h>
#include "notifier.h"

int main() {
    int type;
    char message[256];
    
    // اقرأ نوع الإشعار (1 للبريد الإلكتروني، 2 للرسائل القصيرة)
    scanf("%d", &type);
    getchar(); // استهلك السطر الجديد
    
    // اقرأ الرسالة
    fgets(message, sizeof(message), stdin);
    // أزل السطر الجديد اللاحق إن وُجد
    int len = 0;
    while (message[len] != '\0') len++;
    if (len > 0 && message[len-1] == '\n') message[len-1] = '\0';
    
    // TODO: أنشئ المُبلِّغ المناسب بناءً على النوع
    // استخدم create_email_notifier() للنوع 1
    // استخدم create_sms_notifier() للنوع 2
    
    // TODO: استدعِ دالة notify عبر الواجهة
    // notifier.notify(message);
    
    return 0;
}
quiz iconاختبر نفسك

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

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم C عبر الإنترنت