منصة التعلم الإلكتروني
جزء من قسم Object Oriented Programming في رحلة C++ على Coddy — الدرس 103 من 104.
التحدي
سهللنقم ببناء منصة تعليم إلكتروني تجمع بين جميع مفاهيم البرمجة كائنية التوجه (OOP) التي أتقنتها طوال هذه الدورة. ستقوم بإنشاء نظام يدير الدورات التدريبية، وأنواعاً مختلفة من الدروس، ويتتبع تقدم الطلاب — مما يوضح تدرجات الوراثة، وتعدد الأشكال (polymorphism)، والمؤشرات الذكية (smart pointers)، وأنماط التصميم (design patterns) وهي تعمل في انسجام تام.
ستقوم بتنظيم الكود الخاص بك عبر ستة ملفات:
User.h: أنشئ تدرجاً للمستخدمين مع فئة أساسيةUserوفئتين مشتقتين:StudentوInstructor.يجب أن يكون للفئة الأساسية
Userاسم ومعرف (ID)، مع دالة افتراضيةgetRole()تعيد نوع المستخدم كسلسلة نصية (string)، ودالةgetInfo()تعيد"[name] ([id]) - [role]".تتتبع فئة
Studentمعرفات الدورات المسجل فيها (استخدم vector من السلاسل النصية) وعدد الدروس المكتملة. أضف الدوالenrollInCourse(const std::string& courseId)، وcompletedLesson()لزيادة العداد، وgetCompletedCount().تخزن فئة
Instructorسلسلة نصية للتخصص وتتتبع معرفات الدورات التي يقوم بتدريسها. أضفaddCourse(const std::string& courseId)وgetSpecialty().Lesson.h: ابنِ تدرجاً للدروس باستخدام فئة أساسية مجردة (abstract base class).يجب أن تحتوي الفئة الأساسية
Lessonعلى عنوان ومدة (بالدقائق)، مع دالة افتراضية نقية (pure virtual) باسمcomplete()تعيد رسالة إتمام، ودالةgetType()تعيد نوع الدرس.أنشئ ثلاث فئات مشتقة:
VideoLesson: تحتوي على رابط فيديو (URL). تعيد دالةcomplete()الخاصة بها"Watched video: [title]"QuizLesson: تحتوي على عدد من الأسئلة. تعيد دالةcomplete()الخاصة بها"Completed quiz: [title] ([questions] questions)"TextLesson: تحتوي على عدد الكلمات. تعيد دالةcomplete()الخاصة بها"Read article: [title]"
يجب على كل منها تجاوز
getType()لتعيد"Video"، أو"Quiz"، أو"Text"على التوالي.Course.h: أنشئ فئةCourseتمتلك دروسها باستخدام المؤشرات الذكية.تمتلك الدورة عنواناً، ومعرفاً (ID)، ومعرفاً للمحاضر. قم بتخزين الدروس كـ
std::vector<std::unique_ptr<Lesson>>لأن الدورة تمتلك دروسها بشكل حصري.أضف الدوال التالية:
addLesson(std::unique_ptr<Lesson> lesson)— تنقل ملكية الدرس إلى الدورةgetLessonCount()— تعيد عدد الدروسgetLesson(size_t index)— تعيد مؤشراً للدرس عند ذلك الفهرس (أو nullptr إذا كان غير صالح)displayCurriculum()— تطبع نوع كل درس وعنوانه بالتنسيق"[index]. [Type]: [title]"
LessonFactory.h: قم بتنفيذ نمط المصنع (Factory pattern) لإنشاء أنواع مختلفة من الدروس.أنشئ فئة
LessonFactoryمع دالة ثابتة (static) باسمcreateLesson(const std::string& type, const std::string& title, int duration, const std::string& extra)تعيدstd::unique_ptr<Lesson>.يحدد معامل
typeنوع الدرس المراد إنشاؤه ("video"، أو"quiz"، أو"text"). يحتوي معاملextraعلى بيانات خاصة بالنوع: رابط الفيديو، أو عدد الأسئلة للاختبار (يتم تحويله إلى int)، أو عدد الكلمات للنص (يتم تحويله إلى int).Platform.h: ابنِ فئةPlatformالمركزية التي تنسق كل شيء.قم بتخزين الدورات كـ
std::vector<std::shared_ptr<Course>>والمستخدمين كـstd::vector<std::shared_ptr<User>>.قم بتنفيذ:
addCourse(std::shared_ptr<Course> course)addUser(std::shared_ptr<User> user)findCourse(const std::string& id)— تعيد shared_ptr أو nullptrfindUser(const std::string& id)— تعيد shared_ptr أو nullptrenrollStudent(const std::string& studentId, const std::string& courseId)— تبحث عن كليهما، وتسجل الطالب، وتطبع"Enrolled [name] in [course title]"أو"Enrollment failed"completeLesson(const std::string& studentId, const std::string& courseId, size_t lessonIndex)— تبحث عن الطالب والدورة، وتستدعي دالة complete() الخاصة بالدرس، وتزيد عداد الدروس المكتملة للطالب، وتطبع رسالة الإتمام أو"Could not complete lesson"
main.cpp: اجمع كل شيء معاً لتوضيح عمل منصتك.اقرأ أربعة مدخلات:
- اسم المنصة
- تفاصيل الدورة (بالتنسيق:
title,courseId,instructorId) - تفاصيل الطالب (بالتنسيق:
name,studentId) - الدرس المراد إضافته (بالتنسيق:
type,title,duration,extra)
أنشئ المنصة واعرض
"Welcome to [platform name]!". أنشئ الدورة والطالب، وأضفهما إلى المنصة. استخدم LessonFactory لإنشاء الدرس وأضفه إلى الدورة. اعرض منهج الدورة. سجل الطالب في الدورة. أكمل الدرس الأول (الفهرس 0) لهذا الطالب. أخيراً، اطبع معلومات الطالب وعدد دروسه المكتملة كـ"Completed lessons: [count]".
على سبيل المثال، مع المدخلات CodeAcademy، و C++ Mastery,CPP101,I001، و Alice,S001، و video,Introduction to OOP,30,https://example.com/oop:
Welcome to CodeAcademy!
1. Video: Introduction to OOP
Enrolled Alice in C++ Mastery
Watched video: Introduction to OOP
Alice (S001) - Student
Completed lessons: 1ومع المدخلات LearnHub، و Python Basics,PY100,I002، و Bob,S002، و quiz,Variables Quiz,15,10:
Welcome to LearnHub!
1. Quiz: Variables Quiz
Enrolled Bob in Python Basics
Completed quiz: Variables Quiz (10 questions)
Bob (S002) - Student
Completed lessons: 1يوضح هذا التحدي كيفية هيكلة منصات التعلم الإلكتروني الحقيقية — مع فصل واضح بين المستخدمين والمحتوى والمنصة التي تنسق بينهم. يجعل نمط المصنع (Factory pattern) إنشاء الدروس مرناً، وتضمن المؤشرات الذكية إدارة آمنة للذاكرة، ويسمح لك تعدد الأشكال (polymorphism) بالتعامل مع جميع أنواع الدروس بشكل موحد بينما يتصرف كل منها بشكل فريد.
جرّب بنفسك
#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include "User.h"
#include "Lesson.h"
#include "Course.h"
#include "LessonFactory.h"
#include "Platform.h"
int main() {
// قراءة المدخلات
std::string platformName;
std::getline(std::cin, platformName);
std::string courseDetails; // التنسيق: title,courseId,instructorId
std::getline(std::cin, courseDetails);
std::string studentDetails; // التنسيق: name,studentId
std::getline(std::cin, studentDetails);
std::string lessonDetails; // التنسيق: type,title,duration,extra
std::getline(std::cin, lessonDetails);
// TODO: تحليل courseDetails لاستخراج title و courseId و instructorId
// TODO: تحليل studentDetails لاستخراج name و studentId
// TODO: تحليل lessonDetails لاستخراج type و title و duration و extra
// TODO: إنشاء المنصة وعرض "Welcome to [platform name]!"
// TODO: إنشاء الدورة والطالب، وإضافتهما إلى المنصة
// TODO: استخدام LessonFactory لإنشاء الدرس وإضافته إلى الدورة
// TODO: عرض منهج الدورة
// TODO: تسجيل الطالب في الدورة
// TODO: إكمال الدرس الأول (الفهرس 0) للطالب
// TODO: طباعة معلومات الطالب وعدد الدروس المكتملة
// التنسيق: "Completed lessons: [count]"
return 0;
}
جميع دروس Object Oriented Programming
1أساسيات الـ OOP
الملفات الخارجيةبناء وتجميع (Compilation) لغة C++ملفات الـ Header وملفات الـ Sourceالـ Namespaces والـ Scopeمقدمة في الـ OOP في C++الـ Classes مقابل الـ Objectsالمؤشر 'this'الـ Methods (الدوال الأعضاء)الـ Attributes (بيانات الأعضاء)أساسيات الـ Ctors والـ Dtorsمراجعة - آلة حاسبة بسيطة4خصائص الـ Class
أعضاء الـ Instance مقابل الـ Staticدوال الـ Getters والـ Settersدوال الأعضاء الثابتة (Const)الكلمة المفتاحية Mutableالدوال والمتغيرات الساكنة (Static)الدوال والفئات الصديقة (Friend)مراجعة - مدير الحساب البنكي7الوراثة
الوراثة الأساسيةمستويات الوصول في الوراثةترتيب استدعاء الـ Ctor والـ Dtorإعادة تعريف الدوال (Method Overriding)الدوال الافتراضية والـ VTableالوراثة المتعددةالوراثة الافتراضيةمراجعة - هيكلية الموظفين10نظرة عامة على STL
نظرة عامة وفلسفة STLحاويات STLالـ Iteratorsخوارزميات STLالـ Functors وتعبيرات Lambdaمراجعة - تكرار الكلمات13أنماط التصميم - الجزء الأول
مقدمة في أنماط التصميمنمط Singletonنمط Factory و Abstract Factoryنمط Builderنمط Observerنمط Strategy2إدارة الذاكرة
ذاكرة Stack مقابل Heapالمؤشرات والمراجعالذاكرة الديناميكية (new/delete)المؤشرات الذكية في C++RAII في C++مراجعة - مدير المصفوفات الديناميكية5التغليف (Encapsulation)
محددات الوصول في C++محددات الوصول بشكل متعمقإخفاء المعلوماتStruct مقابل Classالأصناف المتداخلة والداخليةمراجعة - نظام سجلات الطلاب8تعدد الأشكال (Polymorphism)
تعدد الأشكال: وقت التجميع مقابل وقت التشغيلالتحميل الزائد للدوال (Function Overloading)مراجعة الدوال الافتراضية (Virtual Functions)الدوال الافتراضية البحتة (Pure Virtual Functions)الأصناف المجردة (Abstract Classes)تصميم الواجهات (Interface) في C++التحويل الديناميكي (Dynamic Casting) و RTTIملخص - حاسبة الأشكال11مفاهيم OOP المتقدمة
التركيب مقابل الوراثةالـ Mixins عبر CRTPنمط Pimplمحو النوع (Type Erasure)أصناف Enum والأنواع القويةمعالجة الاستثناءات في OOPتسلسلات الاستثناءات المخصصة14أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط قالب الطريقةنمط الحالةنمط التركيبRAII كنمط3المنشئات والموادم
المنشئ الافتراضيالمنشئ ذو المعاملاتمنشئ النسخمنشئ النقلقوائم تهيئة المنشئالمنشئات المفوضةتعمق في الموادمقاعدة الثلاثة / الخمسة / الصفرمراجعة - فئة String6تحميل العوامل (Operator Overloading)
مقدمة في تحميل العواملتحميل العوامل الحسابيةتحميل عوامل المقارنةعوامل Streamتحميل عامل التعيينتحميل العوامل [] و ()عوامل تحويل النوعمراجعة - Matrix Class9القوالب
قوالب الدوالقوالب الأصنافتخصيص القوالبالقوالب المتغيرةأساسيات SFINAE و Type Traitsمراجعة - الحاويات العامة