Menu
Coddy logo textTech

Search with Interfaces

Part of the Object Oriented Programming section of Coddy's GO journey — lesson 101 of 107.

challenge icon

Challenge

Easy

Let's add flexible search capabilities to our Library Management System! You'll implement the Strategy pattern using interfaces, allowing users to search for books by different criteria without modifying the core library code.

You'll organize your code across five files:

  • book.go: Your Book struct from previous lessons with ID, Title, Author, ISBN, and Available fields. Include the NewBook constructor.
  • user.go: Your User struct with ID, Name, Email, and BorrowedBooks fields. Include the NewUser constructor.
  • search.go: Define your search strategy interface and implementations.

    Create a SearchStrategy interface with a single method:

    Match(book *Book, query string) bool

    Implement three search strategies:

    • TitleSearch — matches if the book's title contains the query (case-insensitive)
    • AuthorSearch — matches if the book's author contains the query (case-insensitive)
    • ISBNSearch — matches if the book's ISBN exactly equals the query
  • library.go: Your Library struct with maps for books and users. Add a Search method that accepts any SearchStrategy and a query string, returning a slice of matching book pointers. The method should iterate through all books and use the strategy's Match method to find results.
  • main.go: Build a library with books, then perform searches using different strategies.

    Read the number of books, then for each book read its ID, title, author, and ISBN. Next, read the number of search operations. Each operation consists of a search type (title, author, or isbn) followed by the query string.

    For each search, print Search by [type]: [query] followed by the matching book IDs on the next line, separated by commas. If no books match, print No results instead.

The following inputs will be provided:

  • Number of books, then each book's ID, title, author, ISBN (each on separate lines)
  • Number of searches, then each search type and query (each on separate lines)

For example, given:

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

Your output should be:

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

And given:

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

Your output should be:

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

And given:

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

Your output should be:

Search by title: design
B001,B002

Notice how the Search method works with any strategy—it doesn't know whether it's searching by title, author, or ISBN. This polymorphic approach means you can add new search types (like searching by availability or publication year) simply by creating new structs that implement SearchStrategy!

Try it yourself

package main

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

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

	// Read number of books
	numBooksStr, _ := reader.ReadString('\n')
	numBooks, _ := strconv.Atoi(strings.TrimSpace(numBooksStr))

	// Create library
	library := NewLibrary()

	// Read each book's details
	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)
	}

	// Read number of searches
	numSearchesStr, _ := reader.ReadString('\n')
	numSearches, _ := strconv.Atoi(strings.TrimSpace(numSearchesStr))

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

		// TODO: Select the appropriate search strategy based on searchType
		// searchType can be "title", "author", or "isbn"
		var strategy SearchStrategy

		// TODO: Implement strategy selection logic here

		// TODO: Perform the search using library.Search(strategy, query)

		// TODO: Print the results in the required format
		// Format: "Search by [type]: [query]" followed by matching IDs or "No results"
		fmt.Printf("Search by %s: %s\n", searchType, query)

		// TODO: Print matching book IDs separated by commas, or "No results"
		_ = strategy // Remove this line when you implement the solution
	}
}

All lessons in Object Oriented Programming