Plataforma de E-Learning
Parte de la sección Programación Orientada a Objetos del Journey de C++ de Coddy — lección 103 de 104.
Desafío
FácilVamos a construir una Plataforma de E-Learning que reúna todos los conceptos de POO que has dominado a lo largo de este curso. Crearás un sistema que gestiona cursos, diferentes tipos de lecciones y realiza un seguimiento del progreso de los estudiantes, demostrando jerarquías de herencia, polimorfismo, punteros inteligentes y patrones de diseño trabajando en armonía.
Organizarás tu código en seis archivos:
User.h: Crea una jerarquía de usuarios con una clase baseUsery dos clases derivadas:StudenteInstructor.Tu clase base
Userdebe tener un nombre e ID, con un método virtualgetRole()que devuelva el tipo de usuario como un string, y un métodogetInfo()que devuelva"[name] ([id]) - [role]".La clase
Studentrealiza un seguimiento de los IDs de los cursos inscritos (usa un vector de strings) y el recuento de lecciones completadas. Añade los métodosenrollInCourse(const std::string& courseId),completedLesson()para incrementar el recuento, ygetCompletedCount().La clase
Instructoralmacena un string de especialidad y realiza un seguimiento de los IDs de los cursos que imparte. AñadeaddCourse(const std::string& courseId)ygetSpecialty().Lesson.h: Construye una jerarquía de lecciones utilizando una clase base abstracta.Tu clase base
Lessondebe tener un título y una duración (en minutos), con un método virtual purocomplete()que devuelva un mensaje de finalización, y un métodogetType()que devuelva el tipo de lección.Crea tres clases derivadas:
VideoLesson: Tiene una URL de video. Su métodocomplete()devuelve"Watched video: [title]"QuizLesson: Tiene un número de preguntas. Su métodocomplete()devuelve"Completed quiz: [title] ([questions] questions)"TextLesson: Tiene un recuento de palabras. Su métodocomplete()devuelve"Read article: [title]"
Cada una debe sobrescribir
getType()para devolver"Video","Quiz"o"Text"respectivamente.Course.h: Crea una claseCourseque sea propietaria de sus lecciones utilizando punteros inteligentes.Un curso tiene un título, un ID y un ID de instructor. Almacena las lecciones como
std::vector<std::unique_ptr<Lesson>>ya que el curso posee sus lecciones exclusivamente.Añade los métodos:
addLesson(std::unique_ptr<Lesson> lesson)— transfiere la propiedad de la lección al cursogetLessonCount()— devuelve el número de leccionesgetLesson(size_t index)— devuelve un puntero a la lección en ese índice (o nullptr si no es válido)displayCurriculum()— imprime el tipo y el título de cada lección en el formato"[index]. [Type]: [title]"
LessonFactory.h: Implementa el patrón Factory para crear diferentes tipos de lecciones.Crea una clase
LessonFactorycon un método estáticocreateLesson(const std::string& type, const std::string& title, int duration, const std::string& extra)que devuelva unstd::unique_ptr<Lesson>.El parámetro
typedetermina qué lección crear ("video","quiz"o"text"). El parámetroextracontiene datos específicos del tipo: URL para video, recuento de preguntas para quiz (convertir a int) o recuento de palabras para texto (convertir a int).Platform.h: Construye la clase centralPlatformque coordina todo.Almacena los cursos como
std::vector<std::shared_ptr<Course>>y los usuarios comostd::vector<std::shared_ptr<User>>.Implementa:
addCourse(std::shared_ptr<Course> course)addUser(std::shared_ptr<User> user)findCourse(const std::string& id)— devuelve shared_ptr o nullptrfindUser(const std::string& id)— devuelve shared_ptr o nullptrenrollStudent(const std::string& studentId, const std::string& courseId)— busca ambos, inscribe al estudiante, imprime"Enrolled [name] in [course title]"o"Enrollment failed"completeLesson(const std::string& studentId, const std::string& courseId, size_t lessonIndex)— busca al estudiante y al curso, llama al método complete() de la lección, incrementa el recuento de lecciones completadas del estudiante, imprime el mensaje de finalización o"Could not complete lesson"
main.cpp: Reúne todo para demostrar tu plataforma.Lee cuatro entradas:
- Nombre de la plataforma
- Detalles del curso (formato:
title,courseId,instructorId) - Detalles del estudiante (formato:
name,studentId) - Lección a añadir (formato:
type,title,duration,extra)
Crea la plataforma y muestra
"Welcome to [platform name]!". Crea el curso y el estudiante, añádelos a la plataforma. Usa el LessonFactory para crear la lección y añadirla al curso. Muestra el plan de estudios del curso. Inscribe al estudiante en el curso. Completa la primera lección (índice 0) para ese estudiante. Finalmente, imprime la información del estudiante y su recuento de lecciones completadas como"Completed lessons: [count]".
Por ejemplo, con las entradas CodeAcademy, C++ Mastery,CPP101,I001, Alice,S001, y 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: 1Con las entradas LearnHub, Python Basics,PY100,I002, Bob,S002, y 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: 1Este desafío demuestra cómo se estructuran las plataformas de e-learning reales, con una separación clara entre usuarios, contenido y la plataforma que los coordina. El patrón Factory hace que la creación de lecciones sea flexible, los punteros inteligentes garantizan una gestión de memoria segura y el polimorfismo te permite tratar todos los tipos de lecciones de manera uniforme mientras cada una se comporta de forma única.
Pruébalo tú mismo
#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() {
// Leer entradas
std::string platformName;
std::getline(std::cin, platformName);
std::string courseDetails; // formato: title,courseId,instructorId
std::getline(std::cin, courseDetails);
std::string studentDetails; // formato: name,studentId
std::getline(std::cin, studentDetails);
std::string lessonDetails; // formato: type,title,duration,extra
std::getline(std::cin, lessonDetails);
// TODO: Analizar courseDetails para extraer title, courseId, instructorId
// TODO: Analizar studentDetails para extraer name, studentId
// TODO: Analizar lessonDetails para extraer type, title, duration, extra
// TODO: Crear la plataforma y mostrar "Welcome to [platform name]!"
// TODO: Crear el curso y el estudiante, agregarlos a la plataforma
// TODO: Usar LessonFactory para crear la lección y agregarla al curso
// TODO: Mostrar el plan de estudios del curso
// TODO: Inscribir al estudiante en el curso
// TODO: Completar la primera lección (índice 0) para el estudiante
// TODO: Imprimir la información del estudiante y el recuento de lecciones completadas
// Formato: "Completed lessons: [count]"
return 0;
}
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosConstrucción y compilación en C++Archivos de cabecera y archivos fuenteNamespaces y alcanceIntroducción a OOP en C++Clases vs ObjetosEl puntero 'this'Métodos (Funciones miembro)Atributos (Miembros de datos)Conceptos básicos de Ctors y DtorsResumen - Calculadora simple4Propiedades de clase
Miembros de instancia vs. estáticosGetters y SettersFunciones miembro constPalabra clave mutableMétodos y variables estáticosFunciones y clases amigasResumen - Gestor de cuentas bancarias7Herencia
Herencia básicaNiveles de acceso en la herenciaOrden de llamada de Ctor y DtorSobrescritura de métodosFunciones virtuales y VTableHerencia múltipleHerencia virtualResumen - Jerarquía de empleados2Gestión de memoria
Memoria Stack vs HeapPunteros y referenciasMemoria dinámica (new/delete)Punteros inteligentes en C++RAII en C++Resumen - Gestor de arrays dinámicos5Encapsulamiento
Especificadores de acceso en C++Especificadores de acceso en profundidadOcultamiento de informaciónStruct vs ClassClases anidadas e internasResumen - Sistema de registros de estudiantes8Polimorfismo
Polimorfismo: Compilación vs. Tiempo de ejecuciónSobrecarga de funcionesFunciones virtuales revisadasFunciones virtuales purasClases abstractasDiseño de interfaces en C++Dynamic Casting y RTTIResumen: Calculadora de figuras11Conceptos avanzados de POO
Composición vs. HerenciaMixins mediante CRTPIdioma PimplBorrado de tiposEnum Classes y tipado fuerteManejo de excepciones en POOJerarquías de excepciones personalizadas14Patrones de diseño - Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositeRAII como patrón3Constructores y Destructores
Constructor por defectoConstructor parametrizadoConstructor de copiaConstructor de movimientoListas de inicialización del constructorConstructores delegadosAnálisis profundo del destructorRegla de tres / cinco / ceroResumen - Clase String6Sobrecarga de operadores
Introducción a la sobrecarga de operadoresSobrecarga de operadores aritméticosSobrecarga de operadores de comparaciónOperadores de flujo (Stream)Sobrecarga del operador de asignaciónSobrecarga de los operadores [] y ()Operadores de conversión de tiposResumen - Clase Matrix9Plantillas
Plantillas de funcionesPlantillas de clasesEspecialización de plantillasPlantillas variádicasConceptos básicos de SFINAE y Type TraitsResumen - Contenedor genérico