策略模式
问题
Go 中如何实现策略模式?和传统 OOP 有什么区别?
答案
函数类型实现(Go 惯用)
Go 的一等函数使策略模式极其简洁:
// 策略就是函数类型
type SortStrategy func([]int) []int
// 直接传入函数作为策略
func ProcessData(data []int, strategy SortStrategy) []int {
return strategy(data)
}
// 使用
result := ProcessData(data, sort.Ints) // 内置排序
result := ProcessData(data, bubbleSort) // 自定义排序
result := ProcessData(data, func(d []int) []int { // 匿名函数
slices.Reverse(d)
return d
})
接口实现
需要状态或复杂策略时用接口:
// 压缩策略接口
type Compressor interface {
Compress(data []byte) ([]byte, error)
Extension() string
}
type GzipCompressor struct{ level int }
type ZstdCompressor struct{}
func (g *GzipCompressor) Compress(data []byte) ([]byte, error) { /* ... */ }
func (g *GzipCompressor) Extension() string { return ".gz" }
func (z *ZstdCompressor) Compress(data []byte) ([]byte, error) { /* ... */ }
func (z *ZstdCompressor) Extension() string { return ".zst" }
// 使用
type FileProcessor struct {
compressor Compressor
}
func (fp *FileProcessor) Process(data []byte) error {
compressed, err := fp.compressor.Compress(data)
// ...
}
http.Handler 就是策略模式
标准库中 http.Handler 接口天然就是策略模式:
// 不同的 Handler 就是不同的处理策略
mux.Handle("/api", apiHandler)
mux.Handle("/static", fileHandler)
常见面试问题
Q1: 什么时候用函数,什么时候用接口?
答案:
- 函数类型:策略简单、无状态、只有一个方法 →
func(...) ... - 接口:策略有多个方法、需要持有状态、需要 Mock 测试 →
interface
经验法则:先用函数,复杂了再提取接口。
Q2: Go 标准库中有哪些策略模式?
答案:
sort.Interface:自定义排序策略http.Handler:请求处理策略io.Writer:写入目标策略(文件/网络/Buffer)hash.Hash:哈希算法策略