forked from steger/pr3-sose2026
103 lines
3.5 KiB
Go
103 lines
3.5 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"gitty.informatik.th-mannheim.de/steger/pr3-sose2026/go/04-design-pattern/patterns"
|
|
)
|
|
|
|
// Counter is a concrete implementation of the Subject interface, which maintains a count and notifies observers whenever the count changes
|
|
type Counter struct {
|
|
patterns.Subject // Embedding the Subject interface allows Counter to inherit its methods and be treated as a Subject, enabling it to register observers and notify them of changes
|
|
Count int
|
|
}
|
|
|
|
// NewCounter creates and returns a new instance of the Counter struct, initializing the embedded Subject using the NewSubject function from the patterns package
|
|
func NewCounter() Counter {
|
|
return Counter{patterns.NewSubject(), 0}
|
|
}
|
|
|
|
// Inc increments the counter's count and notifies all registered observers of the change
|
|
func (c *Counter) Inc() {
|
|
c.Count++
|
|
c.Notify()
|
|
}
|
|
|
|
// Dec decrements the counter's count and notifies all registered observers of the change
|
|
func (c *Counter) Dec() {
|
|
c.Count--
|
|
c.Notify()
|
|
}
|
|
|
|
// CountPrinter is a concrete implementation of the Observer interface, which prints the current count whenever it receives an update notification from the Counter
|
|
type CountPrinter struct {
|
|
counter *Counter
|
|
}
|
|
|
|
func (cp *CountPrinter) Update() {
|
|
fmt.Println("count updated to ", cp.counter.Count)
|
|
}
|
|
|
|
var _ patterns.Observer = (*CountPrinter)(nil) // Compile-time assertion to ensure CountPrinter implements the Observer interface
|
|
|
|
// CounterHistory is a concrete implementation of the Observer interface, which maintains a history of the counter's count values whenever it receives an update notification from the Counter
|
|
type CounterHistory struct {
|
|
counter *Counter
|
|
history []int
|
|
}
|
|
|
|
// Update appends the current count value to the history slice whenever it receives an update notification from the Counter
|
|
func (ch *CounterHistory) Update() {
|
|
ch.history = append(ch.history, ch.counter.Count)
|
|
}
|
|
|
|
var _ patterns.Observer = (*CounterHistory)(nil) // Compile-time assertion to ensure CounterHistory implements the Observer interface
|
|
|
|
// The main function demonstrates the usage of the Counter, CountPrinter, and CounterHistory in an interactive command-line application.
|
|
// It allows the user to increment or decrement the counter and see the updates printed, while also maintaining a history of count values.
|
|
func main() {
|
|
// Create a new Counter instance, which will serve as the Subject in the Observer pattern
|
|
counter := NewCounter()
|
|
|
|
// Create a new CounterHistory instance and register it as an observer of the counter to track the history of count values
|
|
history := CounterHistory{&counter, []int{}}
|
|
counter.Register(&history)
|
|
|
|
// Create a new CountPrinter instance and register it as an observer of the counter to print the current count whenever it changes
|
|
printer := CountPrinter{&counter}
|
|
counter.Register(&printer)
|
|
printerRegistered := true
|
|
|
|
var input string
|
|
for {
|
|
fmt.Print("Enter a command (+: increment, -: decrement, q: quit): ")
|
|
fmt.Scanln(&input)
|
|
|
|
if len(input) != 1 {
|
|
fmt.Println("Please enter a single character.")
|
|
continue
|
|
}
|
|
|
|
switch input[0] {
|
|
case '+':
|
|
counter.Inc()
|
|
case '-':
|
|
counter.Dec()
|
|
case 'p':
|
|
// Toggle the registration of the CountPrinter observer. If it's currently registered, unregister it; if it's currently unregistered, register it.
|
|
if printerRegistered {
|
|
counter.Unregister(&printer)
|
|
} else {
|
|
counter.Register(&printer)
|
|
}
|
|
printerRegistered = !printerRegistered
|
|
case 'q':
|
|
fmt.Println("Exiting...")
|
|
fmt.Println(history.history)
|
|
return
|
|
default:
|
|
fmt.Println("Unknown command. Use '+', '-', or 'q'.")
|
|
}
|
|
}
|
|
}
|