Plataforma de E-Learning
Parte da seção Programação Orientada a Objetos do Journey de GO da Coddy. Lição 105 de 107.
Desafio
FácilVamos criar uma Plataforma de E-Learning que gerencia cursos, estudantes e acompanha o progresso de aprendizagem! Você combinará structs, interfaces, composição e polimorfismo para criar um sistema coeso no qual os estudantes podem se matricular em cursos e concluir lições.
Você organizará seu código em cinco arquivos:
lesson.go: Defina uma structLessonque represente unidades individuais de aprendizagem. Cada lição tem umID,TitleeDuration(em minutos). Inclua um construtorNewLessonque retorne um ponteiro para uma Lesson.course.go: Crie uma structCourseque contenha umID,Title,Instructore um slice de ponteiros*Lesson. Inclua um construtorNewCoursee um métodoAddLesson. Implemente também um métodoTotalDuration() intque retorne a soma das durações de todas as lições do curso.student.go: Defina uma structStudentcom os camposID,NameeEmail. Inclua um construtorNewStudent.enrollment.go: É aqui que acontece a mágica do acompanhamento do progresso. Crie uma structEnrollmentque vincule um estudante a um curso e acompanhe quais lições eles concluíram. Ela deve ter:- Um ponteiro para o
Student - Um ponteiro para o
Course - Um mapa
CompletedLessons(ID da lição para booleano)
Defina uma interface
Progressablecom um métodoProgress() float64que retorne uma porcentagem (de 0.0 a 100.0).Implemente estes métodos em Enrollment:
NewEnrollment(student *Student, course *Course) *Enrollment: construtor que inicializa um mapa vazio de lições concluídasCompleteLesson(lessonID string) string: marca uma lição como concluída. Retornalesson not foundse a lição não existir no curso,already completedse já tiver sido concluída oucompletedem caso de sucessoProgress() float64: retorna a porcentagem de lições concluídas (concluídas/total * 100) ou 0.0 se o curso não tiver lições
- Um ponteiro para o
main.go: Construa sua plataforma e processe as operações de matrícula.Leia o ID, o título e o instrutor de um curso. Em seguida, leia o número de lições e o ID, o título e a duração de cada lição. Leia o ID, o nome e o e-mail de um estudante. Crie uma matrícula vinculando o estudante ao curso.
Depois, leia o número de operações. Cada operação é
complete [lessonID]ouprogress. Para operações de conclusão, imprima a mensagem do resultado. Para operações de progresso, imprima o progresso formatado com uma casa decimal, seguido por um símbolo de porcentagem.
As seguintes entradas serão fornecidas:
- ID, título e instrutor do curso (3 linhas)
- Número de lições e, em seguida, o ID, o título e a duração de cada lição (3 linhas cada)
- ID, nome e e-mail do estudante (3 linhas)
- Número de operações e, em seguida, cada operação (1 linha cada)
Por exemplo, considerando:
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 L002Sua saída deve ser:
0.0%
completed
33.3%
already completed
completedE considerando:
C100
Python Basics
Bob Teacher
2
L100
Intro
20
L101
Loops
40
S100
Charlie
charlie@edu.com
4
complete L999
complete L100
complete L101
progressSua saída deve ser:
lesson not found
completed
completed
100.0%Observe como a struct Enrollment usa composição para vincular estudantes e cursos, enquanto a interface Progressable permite que qualquer tipo informe seu status de conclusão. Esse design facilita a extensão. Você poderia adicionar o acompanhamento do progresso a lições individuais ou a trilhas de aprendizagem inteiras usando a mesma interface!
Experimente você mesmo
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// Função auxiliar para ler uma linha
readLine := func() string {
scanner.Scan()
return strings.TrimSpace(scanner.Text())
}
// Ler informações do curso
courseID := readLine()
courseTitle := readLine()
courseInstructor := readLine()
// TODO: Criar o curso usando NewCourse
_ = courseID
_ = courseTitle
_ = courseInstructor
// Ler o número de lições
numLessons, _ := strconv.Atoi(readLine())
// TODO: Ler cada lição e adicionar ao curso
for i := 0; i < numLessons; i++ {
lessonID := readLine()
lessonTitle := readLine()
lessonDuration, _ := strconv.Atoi(readLine())
// TODO: Criar a lição e adicionar ao curso
_ = lessonID
_ = lessonTitle
_ = lessonDuration
}
// Ler informações do aluno
studentID := readLine()
studentName := readLine()
studentEmail := readLine()
// TODO: Criar o aluno usando NewStudent
_ = studentID
_ = studentName
_ = studentEmail
// TODO: Criar a matrícula vinculando o aluno ao curso
// Ler o número de operações
numOps, _ := strconv.Atoi(readLine())
// Processar cada operação
for i := 0; i < numOps; i++ {
operation := readLine()
if operation == "progress" {
// TODO: Chamar Progress() e imprimir com o formato "%.1f%%"
fmt.Println("0.0%") // Substitua pelo progresso real
} else if strings.HasPrefix(operation, "complete ") {
lessonID := strings.TrimPrefix(operation, "complete ")
// TODO: Chame CompleteLesson e imprima o resultado
_ = lessonID
fmt.Println("") // Substitua pelo resultado real
}
}
}
Todas as lições de Programação Orientada a Objetos
1Fundamentos de OOP em Go
Arquivos ExternosWorkspace e Módulos do GoPacotes e ImportsNomes Exportados vs. Não ExportadosIntrodução à OOP em GoStructs como ClassesDefinindo Métodos em StructsReceptores de Ponteiro vs. de ValorInicialização de StructsFunções ConstrutorasRecapitulação — Calculadora Simples4Interfaces
Introdução às InterfacesImplementação ImplícitaInterface como ContratoInterface Vazia (any)Asserção de TipoSwitch de TipoComposição de InterfacesInterfaces Stringer e ErrorRecapitulação - Calculadora de Formas7Encapsulamento
Campos Exportados vs. Não ExportadosEncapsulamento no Nível de PacoteMétodos Getters e SettersOcultação de Informações em GoRecapitulação - Registros de Alunos10Genéricos (Go 1.18+)
Introdução aos genéricosParâmetros de tipoRestrições de tipoStructs genéricasAlternativa para métodos genéricosRecapitulação - Coleção genérica13Padrões de Projeto — Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão Abstract FactoryPadrão ObserverPadrão Strategy2Tipos e Structs em Profundidade
Tipos Básicos e CompostosDefinições de Tipos PersonalizadosTags de StructStructs AnônimasStructs AninhadasValores Zero e PadrõesRecapitulação - Livro de Contatos5Composição em vez de herança
Por que Go não tem herançaNoções básicas de incorporação de structsPromoção de métodosIncorporação de várias structsIncorporação vs agregaçãoOcultação de métodos incorporadosRecapitulação - Hierarquia de funcionários8Tratamento de Erros e OOP
A interface errorTipos de Erro PersonalizadosEncapsulamento de Erros (fmt.Errorf)Erros Sentinelaerrors.Is() e errors.As()Panic, Defer e RecoverRecapitulação - Analisador de Arquivos3Ponteiros e Memória
Fundamentos de Ponteiros em GoPonteiros para StructsPassagem por Valor vs. ReferênciaA Função new()Coleta de Lixo em GoRecapitulação - Construtor de Lista Ligada6Polimorfismo em Go
Polimorfismo via InterfacesDuck Typing em GoRegras de Satisfação de InterfacesColeções PolimórficasInjeção de DependênciasRecapitulação - Processador de Pagamentos9Concorrência e OOP
Fundamentos de GoroutinesCanais e comunicaçãoCanais com e sem bufferInstrução selectsync.Mutex e sync.RWMutexsync.WaitGroupDesign de structs thread-safeRevisão - Worker PoolPratique por conta própria: Compilador de Go online