发布时间:2024-12-23 01:22:54
在需要使用单例的地方,可以使用sync.Once来保证只有一个实例被创建。例如,一个日志记录器:
```go type Logger struct { logLevel int //... } var instance *Logger var once sync.Once func GetInstance() *Logger { once.Do(func() { instance = &Logger{logLevel: 1} }) return instance } ``` 由于sync.Once只会执行一次,因此在多个goroutine尝试获取Logger实例时,只会执行一次实例创建过程,确保了单例的唯一性。在Golang中,可以使用接口和回调函数来实现观察者模式。一个简单的示例是,当某个状态变化时,通知所有的观察者:
```go type Observer interface { Update() } type Subject struct { observers []Observer } func (s *Subject) Attach(observer Observer) { s.observers = append(s.observers, observer) } func (s *Subject) Notify() { for _, observer := range s.observers { observer.Update() } } ``` 在被观察者状态发生改变时,通过调用`Notify`方法通知所有观察者进行更新。一个简单的示例是,根据不同的支付策略选择不同的支付方式:
```go type PaymentStrategy interface { Pay(amount int) } type CreditCardPayment struct{} func (c *CreditCardPayment) Pay(amount int) { fmt.Printf("Paid %d via credit card\n", amount) } type CashPayment struct{} func (c *CashPayment) Pay(amount int) { fmt.Printf("Paid %d in cash\n", amount) } type ShoppingCart struct { paymentStrategy PaymentStrategy } func (s *ShoppingCart) SetPaymentStrategy(strategy PaymentStrategy) { s.paymentStrategy = strategy } func (s *ShoppingCart) Pay(amount int) { s.paymentStrategy.Pay(amount) } ``` 通过设置不同的支付策略,可以在运行时选择不同的支付方式。一个简单的示例是,在不修改原有文件读取功能的基础上,添加缓存功能:
```go type Reader interface { Read() string } type FileReader struct{} func (f *FileReader) Read() string { // 读取文件内容 return "File content" } type FileReaderWithCache struct { reader Reader } func (f *FileReaderWithCache) Read() string { // 先尝试从缓存中读取,若不存在则调用原有的读取方法 return "Data from cache: " + f.reader.Read() } ``` 通过嵌入`Reader`接口,并在`Read`方法前后进行功能扩展,实现了对`FileReader`的装饰。