مراجعة: Logger Factory
جزء من قسم Object Oriented Programming في رحلة C على Coddy — الدرس 57 من 61.
التحدي
سهللنقم ببناء Logger Factory (مصنع مسجل الأحداث) — وهو نظام يوضح قوة الجمع بين نمط المصنع (Factory pattern) وتعدد الأشكال (polymorphism). سيقوم المصنع الخاص بك بإنشاء تطبيقات مختلفة لمسجل الأحداث بناءً على علامة تكوين (configuration flag)، مما يسمح للكود بالتبديل بين إخراج وحدة التحكم التفصيلي والتسجيل "الصامت" (dummy) دون تغيير كيفية استخدام مسجلات الأحداث.
ستقوم بتنظيم الكود الخاص بك عبر ثلاثة ملفات:
logger.h: قم بتعريف هيكلLoggerالذي يعمل كواجهة — يجب أن يحتوي على مؤشر دالة لـlogيأخذLogger*ورسالةconst char*. أعلن عن دالة المصنعcreate_loggerالتي تأخذ علامة عدد صحيح (1 لوحدة التحكم، 0 للـ dummy) وتعيدLogger*. أعلن أيضًا عن دالةfree_loggerللتنظيف.logger.c: قم بتنفيذ نوعين ملموسين من مسجلات الأحداث. يقومConsoleLoggerبتضمينLoggerكعضو أول له ولديه دالة تسجيل تطبع الرسائل بتنسيق[LOG] message. يقومDummyLoggerأيضًا بتضمينLoggerولكن دالة التسجيل الخاصة به لا تفعل شيئًا — فهي ببساطة تعود دون طباعة. أنشئ دوال بناء (constructor functions) لكل نوع تقوم بتخصيص الذاكرة وربط دالة التسجيل المناسبة. ثم قم بتنفيذcreate_loggerكمصنع يتحقق من العلامة ويعيد نوع المسجل المناسب كـLogger*. قم بتنفيذfree_loggerلتحرير الذاكرة.main.c: اقرأ عددًا صحيحًا (1 أو 0) لتحديد نوع المسجل الذي سيتم إنشاؤه. استخدم المصنع الخاص بك لإنشاء المسجل المناسب، ثم استدعِ دالةlogالخاصة به مع رسالتين:"Starting application"و"Shutting down". أخيرًا، قم بتحرير المسجل.
سيتلقى برنامجك مدخلاً واحدًا: عدد صحيح يشير إلى نوع المسجل (1 لوحدة التحكم، 0 للـ dummy).
مثال على المخرجات عندما يكون الإدخال 1:
[LOG] Starting application
[LOG] Shutting downمثال على المخرجات عندما يكون الإدخال 0:
(لا توجد مخرجات — يتجاهل المسجل الصامت جميع الرسائل بصمت)
الأناقة هنا تكمن في أن main.c يستخدم المسجل بشكل متطابق بغض النظر عن النوع الذي يتلقاه. يقرر المصنع ما سيتم إنشاؤه، ويضمن تعدد الأشكال تنفيذ السلوك الصحيح. هذا النمط لا يقدر بثمن في التطبيقات الحقيقية حيث قد ترغب في تسجيل تفصيلي أثناء التطوير ولكن تشغيل صامت في مرحلة الإنتاج.
جرّب بنفسك
#include <stdio.h>
#include "logger.h"
int main() {
// قراءة علامة نوع الـ logger (1 لـ console، و0 لـ dummy)
int flag;
scanf("%d", &flag);
// TODO: استخدم الـ factory لإنشاء الـ logger المناسب
// TODO: استدعِ دالة log الخاصة بالـ logger مع "Starting application"
// TODO: استدعِ دالة log الخاصة بالـ logger مع "Shutting down"
// TODO: قم بتحرير الـ logger
return 0;
}
جميع دروس Object Oriented Programming
1أساسيات البرمجة التركيبية
ملفات الترويسةحواجز التضمينملفات المصدرالدوال الساكنةمراجعة: آلة حاسبة تركيبية4التغليف (Encapsulation)
مفهوم الـ Opaque Pointersتعريف الـ Opaque Structsالـ Getters والـ Settersالتحقق من البيانات في الـ Settersملخص: الصندوق السري2الكائنات والأساليب
الـ Structs ككائناتمؤشر 'Self'صحة استخدام Constالمؤشر مقابل القيمةالأساليب المساعدةملخص: Point Manager5مشروع: حساب بنكي بسيط
إعداد المشروعتنفيذ الحساب3دورة حياة الكائن
نمط المنشئ (Constructor Pattern)نمط الهادم (Destructor Pattern)تهيئة الـ Stackالنسخ العميق (Deep Copy)مراجعة: String Wrapper6الوراثة عبر التركيب
تضمين الـ Structقاعدة العضو الأولالوصول إلى أعضاء الأبعملية الـ Upcastingمراجعة: هرمية الأشكال9مشروع: رسّام الأشكال
نظرة عامة على المشروعتنفيذ الدائرة