Menu
Coddy logo textTech

Busca com interfaces

Parte da seção Programação Orientada a Objetos do Journey de GO da Coddy. Lição 101 de 107.

challenge icon

Desafio

Fácil

Vamos adicionar recursos flexíveis de pesquisa ao nosso Sistema de Gerenciamento de Biblioteca! Você implementará o padrão Strategy usando interfaces, permitindo que os usuários pesquisem livros por diferentes critérios sem modificar o código principal da biblioteca.

Você organizará seu código em cinco arquivos:

  • book.go: sua struct Book das lições anteriores, com os campos ID, Title, Author, ISBN e Available. Inclua o construtor NewBook.
  • user.go: sua struct User, com os campos ID, Name, Email e BorrowedBooks. Inclua o construtor NewUser.
  • search.go: defina sua interface de estratégia de pesquisa e suas implementações.

    Crie uma interface SearchStrategy com um único método:

    Match(book *Book, query string) bool

    Implemente três estratégias de pesquisa:

    • TitleSearch: corresponde quando o título do livro contém a consulta (sem distinção entre maiúsculas e minúsculas)
    • AuthorSearch: corresponde quando o autor do livro contém a consulta (sem distinção entre maiúsculas e minúsculas)
    • ISBNSearch: corresponde quando o ISBN do livro é exatamente igual à consulta
  • library.go: sua struct Library, com mapas para livros e usuários. Adicione um método Search que aceite qualquer SearchStrategy e uma string de consulta, retornando um slice de ponteiros para os livros correspondentes. O método deve iterar por todos os livros e usar o método Match da estratégia para encontrar os resultados.
  • main.go: crie uma biblioteca com livros e, em seguida, execute pesquisas usando diferentes estratégias.

    Leia o número de livros e, depois, para cada livro, leia seu ID, título, autor e ISBN. Em seguida, leia o número de operações de pesquisa. Cada operação consiste em um tipo de pesquisa (title, author ou isbn) seguido pela string de consulta.

    Para cada pesquisa, imprima Search by [type]: [query] e, na linha seguinte, os IDs dos livros correspondentes, ordenados em ordem crescente e separados por vírgulas (um mapa é percorrido em ordem aleatória, portanto, ordene os IDs antes de imprimi-los). Se nenhum livro corresponder, imprima No results.

As seguintes entradas serão fornecidas:

  • Número de livros, seguido pelo ID, título, autor e ISBN de cada livro (cada um em uma linha separada)
  • Número de pesquisas, seguido pelo tipo e pela consulta de cada pesquisa (cada um em uma linha separada)

Por exemplo, dadas as entradas:

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

Sua saída deverá ser:

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

E dadas as entradas:

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

Sua saída deverá ser:

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

E dadas as entradas:

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

Sua saída deverá ser:

Search by title: design
B001,B002

Observe como o método Search funciona com qualquer estratégia. Ele não sabe se está pesquisando por título, autor ou ISBN. Essa abordagem polimórfica significa que você pode adicionar novos tipos de pesquisa (como pesquisar por disponibilidade ou ano de publicação) simplesmente criando novas structs que implementem SearchStrategy!

Experimente você mesmo

package main

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

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

	// Ler o número de livros
	numBooksStr, _ := reader.ReadString('\n')
	numBooks, _ := strconv.Atoi(strings.TrimSpace(numBooksStr))

	// Criar a biblioteca
	library := NewLibrary()

	// Ler os detalhes de cada livro
	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)
	}

	// Ler o número de buscas
	numSearchesStr, _ := reader.ReadString('\n')
	numSearches, _ := strconv.Atoi(strings.TrimSpace(numSearchesStr))

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

		// TODO: Selecione a estratégia de busca apropriada com base em searchType
		// searchType pode ser "title", "author" ou "isbn"
		var strategy SearchStrategy

		// TODO: Implemente a lógica de seleção de estratégia aqui

		// TODO: Realize a busca usando library.Search(strategy, query)

		// TODO: Imprima os resultados no formato exigido
		// Formato: "Search by [type]: [query]" seguido pelos IDs correspondentes ou "No results"
		fmt.Printf("Search by %s: %s\n", searchType, query)

		// TODO: Imprima os IDs dos livros correspondentes separados por vírgulas, ou "No results"
		_ = strategy // Remova esta linha quando implementar a solução
	}
}

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de Go online