Plataforma de aprendizaje en línea
Parte de la sección Programación Orientada a Objetos del Journey de C++ de Coddy. Lección 103 de 104.
Desafío
FácilConstruyamos una plataforma de aprendizaje en línea que reúna todos los conceptos de POO que has dominado a lo largo de este curso. Crearás un sistema que administra cursos y distintos tipos de lecciones, y lleva un seguimiento del progreso de los estudiantes: demostrando cómo las jerarquías de herencia, el polimorfismo, los punteros inteligentes y los patrones de diseño funcionan 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 y un ID, además de un método virtualgetRole()que devuelva el tipo de usuario como una cadena, y un métodogetInfo()que devuelva"[name] ([id]) - [role]".La clase
Studentlleva un registro de los ID de los cursos en los que está inscrito (usa un vector de cadenas) y del número de lecciones completadas. Añade los métodosenrollInCourse(const std::string& courseId),completedLesson()para incrementar el contador, ygetCompletedCount().La clase
Instructoralmacena una cadena con su especialidad y lleva un registro de los ID de los cursos que imparte. AñadeaddCourse(const std::string& courseId)ygetSpecialty().Lesson.h: Crea una jerarquía de lecciones usando una clase base abstracta.Tu clase base
Lessondebe tener un título y una duración (en minutos), además de 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 mediante 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 es el único propietario de sus lecciones.Añade estos 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(): muestra el tipo y el título de cada lección con el formato"[index]. [Type]: [title]"
LessonFactory.h: Implementa el patrón Factory para crear distintos 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: la URL para video, el número de preguntas para quiz (convertido a int) o el recuento de palabras para texto (convertido 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 un shared_ptr o nullptrfindUser(const std::string& id): devuelve un shared_ptr o nullptrenrollStudent(const std::string& studentId, const std::string& courseId): busca ambos, inscribe al estudiante y muestra"Enrolled [name] in [course title]"o"Enrollment failed"completeLesson(const std::string& studentId, const std::string& courseId, size_t lessonIndex): busca al estudiante y el curso, llama al método complete() de la lección, incrementa el recuento de lecciones completadas del estudiante y muestra el mensaje de finalización o"Could not complete lesson"
main.cpp: Reúne todo para mostrar cómo funciona tu plataforma.Lee cuatro entradas:
- Nombre de la plataforma
- Detalles del curso (formato:
title,courseId,instructorId) - Detalles del estudiante (formato:
name,studentId) - Lección que se añadirá (formato:
type,title,duration,extra)
Crea la plataforma y muestra
"Welcome to [platform name]!". Crea el curso y el estudiante, y añádelos a la plataforma. Usa LessonFactory para crear la lección y añadirla al curso. Muestra el currículo del curso. Inscribe al estudiante en el curso. Completa la primera lección (índice 0) para ese estudiante. Por último, muestra la información del estudiante y su recuento de lecciones completadas con el formato"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 aprendizaje en línea reales, con una separación clara entre los usuarios, el contenido y la plataforma que los coordina. El patrón Factory hace flexible la creación de lecciones, los punteros inteligentes garantizan una gestión segura de la memoria y el polimorfismo permite tratar todos los tipos de lecciones de manera uniforme, aunque cada uno se comporte 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 las 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, y añadirlos a la plataforma
// TODO: Usar LessonFactory para crear la lección y añadirla al curso
// TODO: Mostrar el plan de estudios del curso
// TODO: Inscribir al estudiante en el curso
// TODO: Completa la primera lección (índice 0) para el estudiante
// TODO: Imprime la información del estudiante y el número de lecciones completadas
// Formato: "Completed lessons: [count]"
return 0;
}
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de la POO
Archivos externosCompilación y construcción en C++Archivos de cabecera y archivos fuenteEspacios de nombres y ámbitoIntroducción a la POO en C++Clases y objetosEl puntero 'this'Métodos (funciones miembro)Atributos (miembros de datos)Fundamentos de constructores y destructoresRepaso: calculadora sencilla4Propiedades de clase
Miembros de instancia vs. estáticosGetters y settersFunciones miembro constPalabra clave mutableMétodos y variables estáticosFunciones y clases friendRepaso: gestor de cuentas bancarias7Herencia
Herencia básicaNiveles de acceso en la herenciaOrden de llamada de constructores y destructoresSobrescritura de métodosFunciones virtuales y VTableHerencia múltipleHerencia virtualRepaso: jerarquía de empleados2Gestión de memoria
Memoria de pila vs. heapPunteros y referenciasMemoria dinámica (new/delete)Punteros inteligentes en C++RAII en C++Repaso: gestor de arreglos dinámicos5Encapsulación
Especificadores de acceso en C++Especificadores de acceso en profundidadOcultación de informaciónStruct vs. classClases anidadas e internasRepaso: sistema de registros de estudiantes8Polimorfismo
Polimorfismo en compilación y en tiempo de ejecuciónSobrecarga de funcionesRepaso de las funciones virtualesFunciones virtuales purasClases abstractasDiseño de interfaces en C++Conversión dinámica y RTTIRepaso: calculadora de formas11Conceptos avanzados de POO
Composición frente a herenciaMixins mediante CRTPIdiom PimplBorrado de tiposClases enum 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 predeterminadoConstructor con parámetrosConstructor de copiaConstructor de movimientoListas de inicialización del constructorConstructores delegadosAnálisis detallado del destructorRegla de tres / cinco / ceroRepaso: clase String6Sobrecarga de operadores
Introducción a la sobrecarga de operadoresSobrecarga de operadores aritméticosSobrecarga de operadores de comparaciónOperadores de flujoSobrecarga del operador de asignaciónSobrecarga de los operadores [] y ()Operadores de conversión de tipoRepaso: clase Matrix9Plantillas
Plantillas de funcionesPlantillas de clasesEspecialización de plantillasPlantillas variádicasFundamentos de SFINAE y rasgos de tiposRepaso: contenedor genéricoPractica por tu cuenta: Compilador de C++ online