设计模式常通过其独特的语言特性(如接口、组合、并发原语)实现
1.工厂模式(Factory)
通过函数封装对象创建逻辑
Go
package payment
type PaymentMethod interface {
Pay(amount float32) string
}
type CreditCard struct{}
func (c *CreditCard) Pay(amount float32) string {
return fmt.Sprintf("Paid $%.2f via credit card", amount)
}
type PayPal struct{}
func (p *PayPal) Pay(amount float32) string {
return fmt.Sprintf("Paid $%.2f via PayPal", amount)
}
// 工厂函数
func GetPaymentMethod(method string) PaymentMethod {
switch method {
case "creditcard":
return &CreditCard{}
case "paypal":
return &PayPal{}
default:
return nil
}
}
// 使用
pm := payment.GetPaymentMethod("paypal")
fmt.Println(pm.Pay(100)) // Paid $100.00 via PayPal
2.单例模式(Singleton)
使用sync.Once保证线程安全
Go
type Database struct{ /* ... */ }
var (
dbInstance *Database
once sync.Once
)
func GetDB() *Database {
once.Do(func() {
dbInstance = &Database{} // 初始化逻辑
})
return dbInstance
}
// 使用
db1 := GetDB()
db2 := GetDB()
fmt.Println(db1 == db2) // true
3.装饰器模式(Decorator)
通过函数包装增强功能
Go
type HTTPHandler func(http.ResponseWriter, *http.Request)
func LoggingDecorator(h HTTPHandler) HTTPHandler {
return func(w http.ResponseWriter, r *http.Request) {
log.Printf("Request: %s %s", r.Method, r.URL)
h(w, r) // 调用原始处理函数
}
}
// 使用
http.HandleFunc("/", LoggingDecorator(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello!"))
}))
4.观察者模式(Observer)
使用通道实现事件通知
Go
type Event struct{ Data string }
type Publisher struct {
observers []chan Event
mu sync.Mutex
}
func (p *Publisher) Subscribe() chan Event {
p.mu.Lock()
defer p.mu.Unlock()
ch := make(chan Event, 10)
p.observers = append(p.observers, ch)
return ch
}
func (p *Publisher) Notify(event Event) {
p.mu.Lock()
defer p.mu.Unlock()
for _, ch := range p.observers {
ch <- event
}
}
// 使用
pub := Publisher{}
sub := pub.Subscribe()
go func() { pub.Notify(Event{Data: "update"}) }()
fmt.Println(<-sub) // {update}
5.策略模式(Strategy)
通过接口实现算法替换
Go
type Sorter interface {
Sort([]int) []int
}
type BubbleSort struct{}
func (bs BubbleSort) Sort(arr []int) []int { /* 冒泡排序实现 */ }
type QuickSort struct{}
func (qs QuickSort) Sort(arr []int) []int { /* 快速排序实现 */ }
type Client struct {
sorter Sorter
}
func (c *Client) Process(data []int) []int {
return c.sorter.Sort(data)
}
// 使用
client := Client{sorter: QuickSort{}}
result := client.Process([]int{3,1,4})
6.适配器模式(Adapter)
连接不兼容的接口
Go
type LegacyPrinter interface {
Print(s string) string
}
type MyLegacyPrinter struct{}
func (p *MyLegacyPrinter) Print(s string) string {
return fmt.Sprintf("Legacy: %s", s)
}
type ModernPrinter interface {
PrintStored() string
}
type PrinterAdapter struct {
LegacyPrinter LegacyPrinter
Msg string
}
func (p *PrinterAdapter) PrintStored() string {
return p.LegacyPrinter.Print(p.Msg)
}
// 使用
adapter := PrinterAdapter{LegacyPrinter: MyLegacyPrinter{}, Msg: "Hello"}
fmt.Println(adapter.PrintStored()) // Legacy: Hello
7.责任链模式(Chain of Responsibility)
链表式处理请求
Go
type Handler interface {
Handle(request string) string
SetNext(handler Handler)
}
type BaseHandler struct {
next Handler
}
func (b *BaseHandler) SetNext(handler Handler) { b.next = handler }
type AuthHandler struct{ BaseHandler }
func (a *AuthHandler) Handle(request string) string {
if strings.Contains(request, "auth=pass") {
return a.next.Handle(request)
}
return "Auth failed"
}
type LogHandler struct{ BaseHandler }
func (l *LogHandler) Handle(request string) string {
log.Println("Request logged")
return l.next.Handle(request)
}
// 构建责任链
auth := &AuthHandler{}
log := &LogHandler{}
auth.SetNext(log)
fmt.Println(auth.Handle("/path?auth=pass")) // 链式处理
8.Go 特有并发模式
(1).Worker Pool
Go
func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs {
results <- j * 2
}
}
jobs := make(chan int, 100)
results := make(chan int, 100)
// 启动3个worker
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
// 发送任务
for j := 1; j <= 5; j++ {
jobs <- j
}
close(jobs)
(2).Fan-Out/Fan-In
使用多个goroutine处理任务并合并结果
Go
func process(input <-chan int) <-chan int {
out := make(chan int)
go func() {
defer close(out)
for n := range input {
out <- n * n // 平方计算
}
}()
return out
}
// 合并多个channel
func merge(chs ...<-chan int) <-chan int {
var wg sync.WaitGroup
out := make(chan int)
wg.Add(len(chs))
for _, ch := range chs {
go func(c <-chan int) {
for n := range c {
out <- n
}
wg.Done()
}(ch)
}
go func() {
wg.Wait()
close(out)
}()
return out
}
总结:上面示例展示了Go 如何利用接口组合 、闭包 、通道 和
sync包实现经典设计模式,同时体现了 Go 的并发哲学:"用通信共享内存,而非通过共享内存通信"