Suche mit Interfaces
Teil des Abschnitts Objektorientierte Programmierung der GO-Journey von Coddy — Lektion 101 von 107.
Aufgabe
EinfachLassen wir uns flexible Suchfunktionen zu unserem Bibliotheksverwaltungssystem hinzufügen! Sie werden das Strategy-Pattern mithilfe von Interfaces implementieren, was es Benutzern ermöglicht, nach Büchern anhand verschiedener Kriterien zu suchen, ohne den Kerncode der Bibliothek zu ändern.
Sie werden Ihren Code über fünf Dateien organisieren:
book.go: IhrBook-Struct aus den vorherigen Lektionen mit den FeldernID,Title,Author,ISBNundAvailable. Fügen Sie denNewBook-Konstruktor hinzu.user.go: IhrUser-Struct mit den FeldernID,Name,EmailundBorrowedBooks. Fügen Sie denNewUser-Konstruktor hinzu.search.go: Definieren Sie Ihr Suchstrategie-Interface und dessen Implementierungen.Erstellen Sie ein
SearchStrategy-Interface mit einer einzigen Methode:Match(book *Book, query string) boolImplementieren Sie drei Suchstrategien:
TitleSearch— trifft zu, wenn der Titel des Buches die Abfrage enthält (unabhängig von Groß-/Kleinschreibung)AuthorSearch— trifft zu, wenn der Autor des Buches die Abfrage enthält (unabhängig von Groß-/Kleinschreibung)ISBNSearch— trifft zu, wenn die ISBN des Buches exakt der Abfrage entspricht
library.go: IhrLibrary-Struct mit Maps für Bücher und Benutzer. Fügen Sie eineSearch-Methode hinzu, die eine beliebigeSearchStrategyund einen Abfragestring (query) akzeptiert und einen Slice von Buch-Pointern zurückgibt. Die Methode sollte alle Bücher durchlaufen und dieMatch-Methode der Strategie verwenden, um Ergebnisse zu finden.main.go: Erstellen Sie eine Bibliothek mit Büchern und führen Sie dann Suchen mit verschiedenen Strategien durch.Lesen Sie die Anzahl der Bücher ein, dann für jedes Buch dessen ID, Titel, Autor und ISBN. Lesen Sie als Nächstes die Anzahl der Suchvorgänge ein. Jeder Vorgang besteht aus einem Suchtyp (
title,authoroderisbn), gefolgt vom Abfragestring.Geben Sie für jede Suche
Search by [type]: [query]aus, gefolgt von den passenden Buch-IDs in der nächsten Zeile, getrennt durch Kommas. Wenn keine Bücher übereinstimmen, geben Sie stattdessenNo resultsaus.
Die folgenden Eingaben werden bereitgestellt:
- Anzahl der Bücher, dann ID, Titel, Autor und ISBN jedes Buches (jeweils in separaten Zeilen)
- Anzahl der Suchen, dann jeder Suchtyp und die Abfrage (jeweils in separaten Zeilen)
Zum Beispiel, gegeben:
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-1449355739Sollte Ihre Ausgabe wie folgt aussehen:
Search by title: go
B001,B002
Search by author: kennedy
B002
Search by isbn: 978-1449355739
B003Und gegeben:
2
B001
Clean Code
Robert Martin
978-0132350884
B002
The Pragmatic Programmer
David Thomas
978-0135957059
2
title
java
author
martinSollte Ihre Ausgabe wie folgt aussehen:
Search by title: java
No results
Search by author: martin
B001Und gegeben:
2
B001
Design Patterns
Gang of Four
978-0201633610
B002
Head First Design Patterns
Eric Freeman
978-0596007126
1
title
designSollte Ihre Ausgabe wie folgt aussehen:
Search by title: design
B001,B002Beachten Sie, wie die Search-Methode mit jeder Strategie funktioniert — sie weiß nicht, ob sie nach Titel, Autor oder ISBN sucht. Dieser polymorphe Ansatz bedeutet, dass Sie neue Suchtypen hinzufügen können (wie die Suche nach Verfügbarkeit oder Erscheinungsjahr), indem Sie einfach neue Structs erstellen, die SearchStrategy implementieren!
Probier es selbst
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Anzahl der Bücher lesen
numBooksStr, _ := reader.ReadString('\n')
numBooks, _ := strconv.Atoi(strings.TrimSpace(numBooksStr))
// Bibliothek erstellen
library := NewLibrary()
// Details jedes Buches lesen
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)
}
// Anzahl der Suchanfragen lesen
numSearchesStr, _ := reader.ReadString('\n')
numSearches, _ := strconv.Atoi(strings.TrimSpace(numSearchesStr))
// Jede Suche verarbeiten
for i := 0; i < numSearches; i++ {
searchType, _ := reader.ReadString('\n')
searchType = strings.TrimSpace(searchType)
query, _ := reader.ReadString('\n')
query = strings.TrimSpace(query)
// TODO: Wähle die passende Suchstrategie basierend auf searchType aus
// searchType kann "title", "author" oder "isbn" sein
var strategy SearchStrategy
// TODO: Implementiere hier die Logik zur Strategieauswahl
// TODO: Führe die Suche mit library.Search(strategy, query) aus
// TODO: Gib die Ergebnisse im erforderlichen Format aus
// Format: "Search by [type]: [query]" gefolgt von passenden IDs oder "No results"
fmt.Printf("Search by %s: %s\n", searchType, query)
// TODO: Gib die passenden Buch-IDs durch Kommas getrennt aus, oder "No results"
_ = strategy // Entferne diese Zeile, wenn du die Lösung implementierst
}
}
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der Go OOP
Externe DateienGo Workspace & ModulePackages & ImportsExportierte vs. nicht-exportierte NamenEinführung in OOP in GoStructs als KlassenMethoden für Structs definierenPointer- vs. Value-ReceiverStruct-InitialisierungKonstruktor-FunktionenZusammenfassung – Einfacher Taschenrechner4Interfaces
Einführung in InterfacesImplizite ImplementierungInterface als VertragLeeres Interface (any)Type AssertionType SwitchInterface-KompositionStringer & Error InterfacesRückblick - Formen-Rechner7Kapselung
Exportierte vs. nicht exportierte FelderKapselung auf Paket-EbeneGetter- & Setter-MethodenInformation Hiding in GoZusammenfassung - Studierendendatensätze10Generics (Go 1.18+)
Einführung in GenericsTypparameterType ConstraintsGenerische StructsWorkaround für generische MethodenZusammenfassung – Generische Collection2Vertiefung: Typen & Structs
Basis- & zusammengesetzte TypenBenutzerdefinierte TypdefinitionenStruct TagsAnonyme StructsVerschachtelte StructsZero Values & StandardwerteZusammenfassung - Kontaktbuch5Komposition statt Vererbung
Warum Go keine Vererbung hatGrundlagen des Struct EmbeddingMethod PromotionEinbetten mehrerer StructsEmbedding vs. AggregationShadowing eingebetteter MethodenZusammenfassung – Mitarbeiter-Hierarchie8Fehlerbehandlung & OOP
Das error-InterfaceEigene FehlertypenError Wrapping (fmt.Errorf)Sentinel-Fehlererrors.Is() und errors.As()Panic, Defer und RecoverZusammenfassung – Datei-Parser3Zeiger & Speicher
Zeiger-Grundlagen in GoZeiger auf StructsWertübergabe vs. ReferenzübergabeDie new() FunktionGarbage Collection in GoWiederholung – Linked List Builder6Polymorphismus in Go
Polymorphismus über InterfacesDuck Typing in GoInterface-ErfüllungsregelnPolymorphe CollectionsDependency InjectionZusammenfassung – Payment Processor9Nebenläufigkeit & OOP
Goroutines GrundlagenChannels & KommunikationGepufferte vs. ungepufferte ChannelsSelect-Anweisungsync.Mutex & sync.RWMutexsync.WaitGroupThread-sicheres Struct-DesignZusammenfassung - Worker Pool12Fortgeschrittene OOP-Konzepte
Functional Options PatternBuilder-Pattern in GoMethodenverkettungTyp-Aliase vs. DefinitionenReflection-GrundlagenÜberblick zur Code-Generierung15Projekt: Bibliotheksverwaltung
Projektübersicht & StrukturBuch- und Benutzer-Structs