Sistema di prestito
Fa parte della sezione Programmazione orientata agli oggetti del percorso GO di Coddy. Lezione 100 di 107.
Sfida
FacileCostruiamo il sistema di prestito per il nostro progetto di gestione di una biblioteca! Creerai una struttura Library che gestisce raccolte di libri e utenti, con metodi per gestire le operazioni di prestito e restituzione: il tutto con una convalida adeguata.
Organizzerai il codice in quattro file:
book.go: la tua strutturaBookdella lezione precedente, con i campiID,Title,Author,ISBNeAvailable. Includi il costruttoreNewBook, che inizializza i libri come disponibili.user.go: la tua strutturaUserconID,Name,EmaileBorrowedBooks(una slice di ID dei libri). Includi il costruttoreNewUser, che inizializza gli utenti con un elenco dei prestiti vuoto.library.go: crea una strutturaLibraryche memorizza libri e utenti in mappe (con chiavi corrispondenti ai rispettivi ID). Crea questi componenti:- Un costruttore
NewLibraryche inizializza mappe vuote per libri e utenti - Un metodo
AddBookche aggiunge un libro alla biblioteca - Un metodo
AddUserche aggiunge un utente alla biblioteca - Un metodo
Borrowche riceve l’ID di un utente e l’ID di un libro, convalida l’operazione, contrassegna il libro come non disponibile, aggiunge l’ID del libro all’elenco dei prestiti dell’utente e restituisce un errore se qualcosa va storto - Un metodo
Returnche annulla il prestito: contrassegna il libro come disponibile e lo rimuove dall’elenco dei prestiti dell’utente
Il metodo
Borrowdovrebbe restituire questi errori:user not foundse l’ID dell’utente non esistebook not foundse l’ID del libro non esistebook not availablese il libro è già in prestito
Il metodo
Returndovrebbe restituire questi errori:user not foundse l’ID dell’utente non esistebook not foundse l’ID del libro non esistebook not borrowedse il libro è già disponibile
- Un costruttore
main.go: metti insieme tutti gli elementi creando una biblioteca, aggiungendo libri e utenti e poi elaborando le operazioni di prestito e restituzione.Leggi il numero di libri, poi per ogni libro leggi l’ID, il titolo, l’autore e l’ISBN. Poi leggi il numero di utenti e, per ciascun utente, leggi l’ID, il nome e l’indirizzo email. Infine, leggi il numero di operazioni, ognuna delle quali è
borrow [userID] [bookID]oppurereturn [userID] [bookID].Per ogni operazione, stampa
OKse ha esito positivo oppureError: [message]se non riesce.
Verranno forniti i seguenti input:
- Numero di libri, seguito dall’ID, dal titolo, dall’autore e dall’ISBN di ciascun libro (ognuno su una riga separata)
- Numero di utenti, seguito dall’ID, dal nome e dall’indirizzo email di ciascun utente (ognuno su una riga separata)
- Numero di operazioni, seguito da ciascuna operazione su una riga separata
Ad esempio, dato:
2
B001
The Go Programming Language
Alan Donovan
978-0134190440
B002
Clean Code
Robert Martin
978-0132350884
1
U001
Alice Smith
alice@library.com
4
borrow U001 B001
borrow U001 B001
return U001 B001
borrow U002 B001Il tuo output dovrebbe essere:
OK
Error: book not available
OK
Error: user not foundE dato:
1
B100
Design Patterns
Gang of Four
978-0201633610
2
U001
Bob Jones
bob@email.com
U002
Carol White
carol@email.com
3
borrow U001 B100
borrow U002 B100
return U001 B100Il tuo output dovrebbe essere:
OK
Error: book not available
OKE dato:
1
B001
Go in Action
William Kennedy
978-1617291784
1
U001
Dave Miller
dave@test.com
2
return U001 B001
borrow U001 B999Il tuo output dovrebbe essere:
Error: book not borrowed
Error: book not foundNota come Library agisce da coordinatore centrale. Convalida tutte le operazioni prima di modificare lo stato, assicurandosi che libri e utenti rimangano sincronizzati. L’uso di receiver con puntatore permette ai tuoi metodi di modificare i dati effettivamente memorizzati nelle mappe!
Provalo tu
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Leggi il numero di libri
var numBooks int
fmt.Fscanln(reader, &numBooks)
// TODO: Crea una nuova biblioteca
// TODO: Leggi i dettagli di ogni libro (ID, Title, Author, ISBN su righe separate)
// e aggiungili alla biblioteca
for i := 0; i < numBooks; i++ {
id, _ := reader.ReadString('\n')
id = strings.TrimSpace(id)
title, _ := reader.ReadString('\n')
title = strings.TrimSpace(title)
author, _ := reader.ReadString('\n')
author = strings.TrimSpace(author)
isbn, _ := reader.ReadString('\n')
isbn = strings.TrimSpace(isbn)
// TODO: Crea il libro e aggiungilo alla biblioteca
}
// Leggi il numero di utenti
var numUsers int
fmt.Fscanln(reader, &numUsers)
// TODO: Leggi i dettagli di ogni utente (ID, Name, Email su righe separate)
// e aggiungili alla biblioteca
for i := 0; i < numUsers; i++ {
id, _ := reader.ReadString('\n')
id = strings.TrimSpace(id)
name, _ := reader.ReadString('\n')
name = strings.TrimSpace(name)
email, _ := reader.ReadString('\n')
email = strings.TrimSpace(email)
// TODO: Crea l'utente e aggiungilo alla biblioteca
}
// Leggi il numero di operazioni
var numOps int
fmt.Fscanln(reader, &numOps)
// TODO: Elabora ogni operazione
// Formato: "borrow [userID] [bookID]" o "return [userID] [bookID]"
for i := 0; i < numOps; i++ {
line, _ := reader.ReadString('\n')
line = strings.TrimSpace(line)
parts := strings.Split(line, " ")
// TODO: Analizza l'operazione e chiama il metodo appropriato
// Stampa "OK" in caso di successo o "Error: [message]" in caso di errore
}
}
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti di OOP in Go
File esterniWorkspace e moduli GoPacchetti e importazioniNomi esportati e non esportatiIntroduzione all’OOP in GoGli struct come classiDefinire metodi sugli structReceiver con puntatore vs receiver con valoreInizializzazione degli structFunzioni costruttriciRiepilogo - Calcolatrice semplice4Interfacce
Introduzione alle interfacceImplementazione implicitaL’interfaccia come contrattoInterfaccia vuota (any)Asserzione di tipoSwitch sul tipoComposizione di interfacceInterfacce Stringer ed ErrorRipasso - Calcolatore di forme7Incapsulamento
Campi esportati e non esportatiIncapsulamento a livello di packageMetodi Getter e SetterNascondimento delle informazioni in GoRiepilogo - Registri degli studenti10Tipi generici (Go 1.18+)
Introduzione ai tipi genericiParametri di tipoVincoli di tipoStruct genericheSoluzione alternativa per i metodi genericiRiepilogo - Collezione generica13Modelli di progettazione Parte 1
Introduzione ai modelli di progettazioneModello SingletonModello FactoryModello Abstract FactoryModello ObserverModello Strategy2Approfondimento su tipi e struct
Tipi di base e compostiDefinizioni di tipi personalizzatiTag delle structStruct anonimeStruct annidateValori zero e predefinitiRipasso - Rubrica5Composizione invece dell'ereditarietà
Perché Go non ha l'ereditarietàFondamenti dell'embedding delle structPromozione dei metodiEmbedding di più structEmbedding e aggregazione a confrontoMascheramento dei metodi embeddedRiepilogo: gerarchia dei dipendenti8Gestione degli errori e OOP
L'interfaccia errorTipi di errore personalizzatiWrapping degli errori (fmt.Errorf)Errori sentinellaerrors.Is() ed errors.As()Panic, Defer e RecoverRiepilogo - Parser di file11Libreria standard e OOP
io.Reader e io.Writersort.InterfaceInterfaccia fmt.Stringerencoding/json con le structInterfaccia http.HandlerRipasso - modelli REST API14Modelli di progettazione – Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositeMiddleware come Decorator3Puntatori e memoria
Concetti base dei puntatori in GoPuntatori a structPassaggio per valore vs per riferimentoLa funzione new()Garbage collection in GoRiepilogo - Costruttore di liste concatenate6Polimorfismo in Go
Polimorfismo tramite interfacceDuck typing in GoRegole di soddisfacimento delle interfacceCollezioni polimorficheIniezione delle dipendenzeRiepilogo - Elaboratore di pagamenti9Concorrenza e OOP
Basi delle goroutineCanali e comunicazioneCanali bufferizzati vs non bufferizzatiIstruzione selectsync.Mutex e sync.RWMutexsync.WaitGroupProgettazione di struct thread-safeRiepilogo: worker pool12Concetti avanzati di OOP
Pattern delle opzioni funzionaliPattern Builder in GoConcatenamento dei metodiAlias di tipo e definizioni a confrontoNozioni di base sulla reflectionPanoramica sulla generazione del codice15Progetto: Gestione della biblioteca
Panoramica e struttura del progettoStruct per libri e utentiEsercitati da solo: Compilatore Go online