Plateforme d'E-Learning
Fait partie de la section Programmation Orientée Objet du Journey GO de Coddy — leçon 105 sur 107.
Défi
FacileConstruisons une plateforme d'apprentissage en ligne qui gère des cours, des étudiants et suit les progrès d'apprentissage ! Vous combinerez des structures (structs), des interfaces, la composition et le polymorphisme pour créer un système cohérent où les étudiants peuvent s'inscrire à des cours et terminer des leçons.
Vous organiserez votre code sur cinq fichiers :
lesson.go: Définissez une structureLessonreprésentant des unités d'apprentissage individuelles. Chaque leçon possède unID, unTitleet uneDuration(en minutes). Incluez un constructeurNewLessonqui retourne un pointeur vers une Lesson.course.go: Créez une structureCoursequi contient unID, unTitle, unInstructoret une tranche (slice) de pointeurs*Lesson. Incluez un constructeurNewCourseet une méthodeAddLesson. Implémentez également une méthodeTotalDuration() intqui retourne la somme des durées de toutes les leçons du cours.student.go: Définissez une structureStudentavec les champsID,NameetEmail. Incluez un constructeurNewStudent.enrollment.go: C'est ici que la magie du suivi des progrès s'opère. Créez une structureEnrollmentqui lie un étudiant à un cours et suit les leçons qu'il a terminées. Elle doit avoir :- Un pointeur vers le
Student - Un pointeur vers le
Course - Une map
CompletedLessons(ID de la leçon vers booléen)
Définissez une interface
Progressableavec une méthodeProgress() float64qui retourne un pourcentage (0.0 à 100.0).Implémentez ces méthodes sur Enrollment :
NewEnrollment(student *Student, course *Course) *Enrollment— constructeur qui initialise une map de leçons terminées videCompleteLesson(lessonID string) string— marque une leçon comme terminée. Retourne"lesson not found"si la leçon n'existe pas dans le cours,"already completed"si elle est déjà faite, ou"completed"en cas de succèsProgress() float64— retourne le pourcentage de leçons terminées (terminées/total * 100), ou 0.0 si le cours n'a pas de leçons
- Un pointeur vers le
main.go: Construisez votre plateforme et traitez les opérations d'inscription.Lisez l'ID, le titre et l'instructeur d'un cours. Lisez ensuite le nombre de leçons et l'ID, le titre et la durée de chaque leçon. Lisez l'ID, le nom et l'e-mail d'un étudiant. Créez une inscription (enrollment) liant l'étudiant au cours.
Ensuite, lisez le nombre d'opérations. Chaque opération est soit
"complete [lessonID]"soit"progress". Pour les opérations complete, affichez le message de résultat. Pour les opérations progress, affichez le progrès formaté avec une décimale suivi d'un signe de pourcentage.
Les entrées suivantes seront fournies :
- ID du cours, Titre, Instructeur (3 lignes)
- Nombre de leçons, puis l'ID, le Titre, la Durée de chaque leçon (3 lignes chacune)
- ID de l'étudiant, Nom, E-mail (3 lignes)
- Nombre d'opérations, puis chaque opération (1 ligne chacune)
Par exemple, étant donné :
C001
Go Fundamentals
Jane Smith
3
L001
Variables
30
L002
Functions
45
L003
Structs
60
S001
Alice
alice@learn.com
5
progress
complete L001
progress
complete L001
complete L002Votre sortie devrait être :
0.0%
completed
33.3%
already completed
completedEt étant donné :
C100
Python Basics
Bob Teacher
2
L100
Intro
20
L101
Loops
40
S100
Charlie
charlie@edu.com
4
complete L999
complete L100
complete L101
progressVotre sortie devrait être :
lesson not found
completed
completed
100.0%Remarquez comment la structure Enrollment utilise la composition pour lier les étudiants et les cours ensemble, tandis que l'interface Progressable permet à n'importe quel type de rapporter son état d'avancement. Cette conception facilite l'extension — vous pourriez ajouter le suivi des progrès à des leçons individuelles ou à des parcours d'apprentissage entiers en utilisant la même interface !
Essayez vous-même
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// Fonction auxiliaire pour lire une ligne
readLine := func() string {
scanner.Scan()
return strings.TrimSpace(scanner.Text())
}
// Lire les informations du cours
courseID := readLine()
courseTitle := readLine()
courseInstructor := readLine()
// TODO: Créer le cours en utilisant NewCourse
_ = courseID
_ = courseTitle
_ = courseInstructor
// Lire le nombre de leçons
numLessons, _ := strconv.Atoi(readLine())
// TODO: Lire chaque leçon et l'ajouter au cours
for i := 0; i < numLessons; i++ {
lessonID := readLine()
lessonTitle := readLine()
lessonDuration, _ := strconv.Atoi(readLine())
// TODO: Créer la leçon et l'ajouter au cours
_ = lessonID
_ = lessonTitle
_ = lessonDuration
}
// Lire les informations de l'étudiant
studentID := readLine()
studentName := readLine()
studentEmail := readLine()
// TODO: Créer l'étudiant en utilisant NewStudent
_ = studentID
_ = studentName
_ = studentEmail
// TODO: Créer l'inscription liant l'étudiant au cours
// Lire le nombre d'opérations
numOps, _ := strconv.Atoi(readLine())
// Traiter chaque opération
for i := 0; i < numOps; i++ {
operation := readLine()
if operation == "progress" {
// TODO: Appeler Progress() et afficher avec le format "%.1f%%"
fmt.Println("0.0%") // Remplacer par la progression réelle
} else if strings.HasPrefix(operation, "complete ") {
lessonID := strings.TrimPrefix(operation, "complete ")
// TODO: Appeler CompleteLesson et afficher le résultat
_ = lessonID
fmt.Println("") // Remplacer par le résultat réel
}
}
}
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO en Go
Fichiers externesEspace de travail et Modules GoPackages et ImportsNoms exportés vs non exportésIntroduction à la POO en GoLes Structs comme ClassesDéfinir des méthodes sur les StructsReceveurs par pointeur vs par valeurInitialisation de StructsFonctions constructeursRécapitulatif - Calculatrice simple4Interfaces
Introduction aux interfacesImplémentation impliciteL'interface comme contratInterface vide (any)Assertion de typeType SwitchComposition d'interfacesInterfaces Stringer & ErrorRécapitulatif - Calculateur de formes7Encapsulation
Champs exportés vs non exportésEncapsulation au niveau du packageMéthodes Getter & SetterMasquage d'informations en GoRécapitulatif - Dossiers étudiants10Génériques (Go 1.18+)
Introduction aux génériquesParamètres de typeContraintes de typeStructures génériquesContournement pour les méthodes génériquesRécapitulatif - Collections génériques13Patrons de conception, Partie 1
Introduction aux Design PatternsPatron SingletonPatron FactoryPatron Abstract FactoryPatron ObserverPatron Strategy2Exploration approfondie des Types et Structs
Types de base et compositesDéfinitions de types personnalisésTags de StructStructs anonymesStructs imbriquéesValeurs par défaut et Zero ValuesRécapitulatif - Carnet de contacts5Composition plutôt qu'héritage
Pourquoi Go n'a pas d'héritageLes bases de l'imbrication de structsPromotion de méthodesImbriquer plusieurs structsImbrication vs AgrégationMasquage de méthodes imbriquéesRécapitulatif - Hiérarchie des employés8Gestion des erreurs & POO
L'interface errorTypes d'erreurs personnalisésError Wrapping (fmt.Errorf)Erreurs sentinelleserrors.Is() et errors.As()Panic, Defer et RecoverRécapitulatif - File Parser11Bibliothèque standard et POO
io.Reader & io.WriterL'interface sort.InterfaceL'interface fmt.Stringerencoding/json avec les StructsL'interface http.HandlerRécapitulatif - Modèles d'API REST14Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositeMiddleware en tant que Décorateur3Pointeurs et Mémoire
Bases des pointeurs en GoPointeurs vers des structsPassage par valeur vs référenceLa fonction new()Garbage Collection en GoRécapitulatif - Constructeur de liste chaînée6Le polymorphisme en Go
Le polymorphisme via les interfacesLe Duck Typing en GoRègles de satisfaction des interfacesCollections polymorphesInjection de dépendancesRécapitulatif - Processeur de paiement9Concurrence et POO
Bases des GoroutinesChannels et CommunicationChannels avec buffer vs sans bufferL'instruction Selectsync.Mutex et sync.RWMutexsync.WaitGroupConception de structures Thread-SafeRécapitulatif - Worker Pool