学一学Go中常见的几种设计模式和对应的示例
单例模式
确保一个类型只有一个实例,同时提供一个全局访问点。
Go
package main
import "fmt"
type Singleton struct {
data string
}
var instance *Singleton
func GetInstance() *Singleton {
if instance == nil {
instance = &Singleton{data: "singleton instance"}
}
return instance
}
func main() {
singleton1 := GetInstance()
singleton2 := GetInstance()
if singleton1 == singleton2 {
fmt.Println("Both singletons are the same instance")
// Both singletons are the same instance
} else {
fmt.Println("Different instance")
}
}
工厂模式
通过工厂方法创建对象,而无需指定创建对象的具体类。虽然创建的对象各不相同,但是由于他们都实现了相同的接口,对应的接口类型是一样的。
Go
package main
import "fmt"
type Product interface {
GetInfo() string
}
type ConcreteProduct1 struct {
}
func (p *ConcreteProduct1) GetInfo() string {
return "Product 1"
}
type ConcreteProduct2 struct {
}
func (p *ConcreteProduct2) GetInfo() string {
return "Product 2"
}
type Factory struct {
}
func (f *Factory) CreateProduct(productType int) Product {
switch productType {
case 1:
return &ConcreteProduct1{}
case 2:
return &ConcreteProduct2{}
default:
return nil
}
}
func main() {
factory := &Factory{}
product1 := factory.CreateProduct(1)
product2 := factory.CreateProduct(2)
fmt.Println(product1.GetInfo()) // Product 1
fmt.Println(product2.GetInfo()) // Product 2
}
装饰器模式
允许向现有对象添加新功能,同时保持其结构不变。主要是使用结构体的嵌套实现继承。
Go
package main
import "fmt"
type Component interface {
Operation() string
}
type ConcreteComponent struct {
}
func (c *ConcreteComponent) Operation() string {
return "Concrete Component"
}
type Decorator struct {
Component
}
func (d *Decorator) Operation() string {
return "Decorator " + d.Component.Operation()
}
func main() {
component := &ConcreteComponent{}
decorator := &Decorator{Component: component}
fmt.Println(component.Operation()) // Concrete Component
fmt.Println(decorator.Operation()) // Decorator Concrete Component
}
观察者模式
定义了对象之间的一对多依赖关系,使得当一个对象改变状态时,其所有依赖对象都会收到通知并自动更新。
Go
package main
import "fmt"
type Observer interface {
Update(string)
}
type Subject struct {
observers []Observer
state string
}
func (s *Subject) Attach(observer Observer) {
s.observers = append(s.observers, observer)
}
func (s *Subject) SetState(state string) {
s.state = state
s.Notify()
}
func (s *Subject) Notify() {
for _, observer := range s.observers {
observer.Update(s.state)
}
}
type ConcreteObserver struct {
name string
}
func (co *ConcreteObserver) Update(state string) {
fmt.Printf("Observer %s received the state: %s\n", co.name, state)
}
func main() {
subject := &Subject{}
observer1 := &ConcreteObserver{name: "Observer 1"}
observer2 := &ConcreteObserver{name: "Observer 2"}
subject.Attach(observer1)
subject.Attach(observer2)
subject.SetState("new state")
// Observer Observer 1 received the state: new state
// Observer Observer 2 received the state: new state
}