7.4 设计模式
单例模式
go
import "sync"
type Singleton struct {
value string
}
var (
instance *Singleton
once sync.Once
)
func GetInstance() *Singleton {
once.Do(func() {
instance = &Singleton{value: "singleton"}
})
return instance
}
// 带参数的单例
var (
configInstance *Config
configOnce sync.Once
)
func GetConfig(path string) *Config {
configOnce.Do(func() {
configInstance = loadConfig(path)
})
return configInstance
}工厂模式
go
// 简单工厂
type Product interface {
Use()
}
type ConcreteProductA struct{}
func (p *ConcreteProductA) Use() { fmt.Println("Using A") }
type ConcreteProductB struct{}
func (p *ConcreteProductB) Use() { fmt.Println("Using B") }
func NewProduct(kind string) Product {
switch kind {
case "A":
return &ConcreteProductA{}
case "B":
return &ConcreteProductB{}
default:
return nil
}
}
// 工厂方法
type Factory interface {
Create() Product
}
type FactoryA struct{}
func (f *FactoryA) Create() Product { return &ConcreteProductA{} }选项模式 (Functional Options)
go
type Server struct {
host string
port int
timeout time.Duration
retries int
}
// Option 函数类型
type Option func(*Server)
// 选项函数
func WithHost(host string) Option {
return func(s *Server) {
s.host = host
}
}
func WithPort(port int) Option {
return func(s *Server) {
s.port = port
}
}
func WithTimeout(timeout time.Duration) Option {
return func(s *Server) {
s.timeout = timeout
}
}
// 构造函数
func NewServer(opts ...Option) *Server {
// 默认值
server := &Server{
host: "localhost",
port: 8080,
timeout: 30 * time.Second,
retries: 3,
}
// 应用选项
for _, opt := range opts {
opt(server)
}
return server
}
// 使用
s := NewServer(
WithHost("example.com"),
WithPort(443),
WithTimeout(time.Minute),
)依赖注入
go
// 手动依赖注入
type Database interface {
Query(string) ([]interface{}, error)
}
type UserRepository struct {
db Database
}
func NewUserRepository(db Database) *UserRepository {
return &UserRepository{db: db}
}
type UserService struct {
repo *UserRepository
}
func NewUserService(repo *UserRepository) *UserService {
return &UserService{repo: repo}
}
// 组合所有依赖
func NewApp() *UserService {
db := NewMySQLDatabase()
repo := NewUserRepository(db)
return NewUserService(repo)
}观察者模式
go
type Observer interface {
Update(event string, data interface{})
}
type Subject struct {
mu sync.RWMutex
observers []Observer
}
func (s *Subject) Attach(o Observer) {
s.mu.Lock()
defer s.mu.Unlock()
s.observers = append(s.observers, o)
}
func (s *Subject) Detach(o Observer) {
s.mu.Lock()
defer s.mu.Unlock()
for i, obs := range s.observers {
if obs == o {
s.observers = append(s.observers[:i], s.observers[i+1:]...)
break
}
}
}
func (s *Subject) Notify(event string, data interface{}) {
s.mu.RLock()
defer s.mu.RUnlock()
for _, o := range s.observers {
o.Update(event, data)
}
}
// 使用
type LogObserver struct{}
func (o *LogObserver) Update(event string, data interface{}) {
fmt.Printf("Event: %s, Data: %v\n", event, data)
}策略模式
go
type Strategy interface {
Execute(data []int) []int
}
type BubbleSort struct{}
func (s *BubbleSort) Execute(data []int) []int {
// 冒泡排序
return data
}
type QuickSort struct{}
func (s *QuickSort) Execute(data []int) []int {
// 快速排序
return data
}
type Sorter struct {
strategy Strategy
}
func (s *Sorter) SetStrategy(strategy Strategy) {
s.strategy = strategy
}
func (s *Sorter) Sort(data []int) []int {
return s.strategy.Execute(data)
}
// 使用
sorter := &Sorter{}
sorter.SetStrategy(&QuickSort{})
result := sorter.Sort([]int{3, 1, 4, 1, 5})