Menu
Coddy logo textTech

Ricerca con interfacce

Fa parte della sezione Programmazione orientata agli oggetti del percorso GO di Coddy. Lezione 101 di 107.

challenge icon

Sfida

Facile

Aggiungiamo funzionalità di ricerca flessibili al nostro sistema di gestione della biblioteca! Implementerai il pattern Strategy usando le interfacce, consentendo agli utenti di cercare libri secondo criteri diversi senza modificare il codice di base della biblioteca.

Organizzerai il codice in cinque file:

  • book.go: La struct Book delle lezioni precedenti, con i campi ID, Title, Author, ISBN e Available. Includi il costruttore NewBook.
  • user.go: La struct User, con i campi ID, Name, Email e BorrowedBooks. Includi il costruttore NewUser.
  • search.go: Definisci l'interfaccia della strategia di ricerca e le relative implementazioni.

    Crea un'interfaccia SearchStrategy con un solo metodo:

    Match(book *Book, query string) bool

    Implementa tre strategie di ricerca:

    • TitleSearch: trova una corrispondenza se il titolo del libro contiene la query (senza distinzione tra maiuscole e minuscole)
    • AuthorSearch: trova una corrispondenza se l'autore del libro contiene la query (senza distinzione tra maiuscole e minuscole)
    • ISBNSearch: trova una corrispondenza se l'ISBN del libro è esattamente uguale alla query
  • library.go: La struct Library, con map per libri e utenti. Aggiungi un metodo Search che accetti qualsiasi SearchStrategy e una stringa di query e restituisca uno slice di puntatori ai libri corrispondenti. Il metodo deve scorrere tutti i libri e usare il metodo Match della strategia per trovare i risultati.
  • main.go: Crea una biblioteca con dei libri, quindi esegui ricerche usando strategie diverse.

    Leggi il numero di libri, quindi, per ciascun libro, leggi l'ID, il titolo, l'autore e l'ISBN. Poi leggi il numero di operazioni di ricerca. Ogni operazione consiste in un tipo di ricerca (title, author o isbn) seguito dalla stringa di query.

    Per ogni ricerca, stampa Search by [type]: [query], seguito dagli ID dei libri corrispondenti sulla riga successiva, ordinati in ordine crescente e separati da virgole (l'iterazione su una map avviene in ordine casuale, quindi ordina gli ID prima di stamparli). Se non corrisponde nessun libro, stampa invece No results.

Verranno forniti i seguenti dati in input:

  • Numero di libri, poi l'ID, il titolo, l'autore e l'ISBN di ciascun libro (ognuno su una riga separata)
  • Numero di ricerche, poi il tipo e la query di ciascuna ricerca (ognuno su una riga separata)

Per esempio, dato:

3
B001
The Go Programming Language
Alan Donovan
978-0134190440
B002
Go in Action
William Kennedy
978-1617291784
B003
Learning Python
Mark Lutz
978-1449355739
3
title
go
author
kennedy
isbn
978-1449355739

L'output dovrebbe essere:

Search by title: go
B001,B002
Search by author: kennedy
B002
Search by isbn: 978-1449355739
B003

E dato:

2
B001
Clean Code
Robert Martin
978-0132350884
B002
The Pragmatic Programmer
David Thomas
978-0135957059
2
title
java
author
martin

L'output dovrebbe essere:

Search by title: java
No results
Search by author: martin
B001

E dato:

2
B001
Design Patterns
Gang of Four
978-0201633610
B002
Head First Design Patterns
Eric Freeman
978-0596007126
1
title
design

L'output dovrebbe essere:

Search by title: design
B001,B002

Nota come il metodo Search funzioni con qualsiasi strategia. Non sa se sta cercando per titolo, autore o ISBN. Questo approccio polimorfico permette di aggiungere nuovi tipi di ricerca (come la ricerca per disponibilità o anno di pubblicazione) semplicemente creando nuove struct che implementano SearchStrategy!

Provalo tu

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Leggi il numero di libri
	numBooksStr, _ := reader.ReadString('\n')
	numBooks, _ := strconv.Atoi(strings.TrimSpace(numBooksStr))

	// Crea la libreria
	library := NewLibrary()

	// Leggi i dettagli di ciascun libro
	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)

		book := NewBook(id, title, author, isbn)
		library.AddBook(book)
	}

	// Leggi il numero di ricerche
	numSearchesStr, _ := reader.ReadString('\n')
	numSearches, _ := strconv.Atoi(strings.TrimSpace(numSearchesStr))

	// Elabora ogni ricerca
	for i := 0; i < numSearches; i++ {
		searchType, _ := reader.ReadString('\n')
		searchType = strings.TrimSpace(searchType)
		query, _ := reader.ReadString('\n')
		query = strings.TrimSpace(query)

		// TODO: Seleziona la strategia di ricerca appropriata in base a searchType
		// searchType può essere "title", "author" o "isbn"
		var strategy SearchStrategy

		// TODO: Implementa qui la logica di selezione della strategia

		// TODO: Esegui la ricerca usando library.Search(strategy, query)

		// TODO: Stampa i risultati nel formato richiesto
		// Formato: "Search by [type]: [query]" seguito dagli ID corrispondenti o da "No results"
		fmt.Printf("Search by %s: %s\n", searchType, query)

		// TODO: Stampa gli ID dei libri corrispondenti separati da virgole, oppure "No results"
		_ = strategy // Rimuovi questa riga quando implementi la soluzione
	}
}

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Go online