이러닝 플랫폼
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 104개 중 103번째.
챌린지
쉬움이 과정 전반에서 익힌 모든 OOP 개념을 하나로 모으는 E-Learning 플랫폼을 구축해 봅시다. 강좌와 다양한 유형의 레슨을 관리하고 학생의 학습 진도를 추적하는 시스템을 만들게 됩니다. 이 과정에서 상속 계층 구조, 다형성, 스마트 포인터, 디자인 패턴이 어떻게 조화롭게 작동하는지 실습하게 됩니다.
코드는 다음 6개의 파일로 구성됩니다.
User.h: 기본User클래스와 두 개의 파생 클래스인Student및Instructor를 사용하여 사용자 계층 구조를 만듭니다.기본
User는 이름(name)과 ID를 가져야 하며, 사용자 유형을 문자열로 반환하는 가상getRole()메서드와"[name] ([id]) - [role]"을 반환하는getInfo()메서드를 포함해야 합니다.Student클래스는 등록된 강좌 ID(문자열 벡터 사용)와 완료된 레슨 수를 추적합니다.enrollInCourse(const std::string& courseId), 카운트를 증가시키는completedLesson(), 그리고getCompletedCount()메서드를 추가하세요.Instructor클래스는 전문 분야(specialty) 문자열을 저장하고 가르치는 강좌 ID를 추적합니다.addCourse(const std::string& courseId)와getSpecialty()를 추가하세요.Lesson.h: 추상 기본 클래스를 사용하여 레슨 계층 구조를 구축합니다.Lesson기본 클래스는 제목(title)과 소요 시간(duration, 분 단위)을 가져야 하며, 완료 메시지를 반환하는 순수 가상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클래스를 만듭니다.강좌는 제목(title), ID, 강사 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) 패턴을 구현합니다.std::unique_ptr<Lesson>을 반환하는 정적 메서드createLesson(const std::string& type, const std::string& title, int duration, const std::string& extra)를 가진LessonFactory클래스를 만듭니다.type매개변수는 생성할 레슨("video","quiz", 또는"text")을 결정합니다.extra매개변수에는 유형별 데이터가 포함됩니다: 비디오의 경우 URL, 퀴즈의 경우 질문 수(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 또는 nullptr을 반환합니다.findUser(const std::string& id)— shared_ptr 또는 nullptr을 반환합니다.enrollStudent(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이 챌린지는 실제 e-learning 플랫폼이 사용자, 콘텐츠, 그리고 이를 조율하는 플랫폼 간의 명확한 분리를 통해 어떻게 구조화되는지 보여줍니다. 팩토리 패턴은 레슨 생성을 유연하게 만들고, 스마트 포인터는 안전한 메모리 관리를 보장하며, 다형성을 통해 모든 레슨 유형을 통일된 방식으로 다루면서도 각기 고유하게 동작하도록 할 수 있습니다.
직접 해보기
#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: course와 student를 생성하고 플랫폼에 추가하기
// TODO: LessonFactory를 사용하여 lesson을 생성하고 course에 추가하기
// TODO: course 커리큘럼 표시하기
// TODO: student를 course에 등록하기
// TODO: student의 첫 번째 레슨(인덱스 0) 완료하기
// TODO: student의 정보와 완료된 레슨 수 출력하기
// 형식: "Completed lessons: [count]"
return 0;
}