Go 语言结构型设计模式深度解析

📚 设计模式概述

在 Go 语言中,虽然缺乏传统的类和继承机制,但通过接口、结构体和组合,我们同样可以优雅地实现各种面向对象设计模式。

🎯 代理模式 (Proxy Pattern)

原理介绍

代理模式为其他对象提供一种代理以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介作用。

核心思想

  • 控制访问:控制对真实对象的访问权限
  • 延迟初始化:在需要时才创建昂贵对象
  • 附加功能:在不修改原对象的情况下添加额外功能

设计方案

go 复制代码
package main

import (
    "fmt"
    "log"
    "time"
)

// 抽象主题接口
type Image interface {
    Display()
    GetSize() int
}

// 真实主题 - 高分辨率图像
type HighResolutionImage struct {
    filename string
    width    int
    height   int
    data     []byte
}

func NewHighResolutionImage(filename string) *HighResolutionImage {
    fmt.Printf("Loading high resolution image: %s\n", filename)
    // 模拟昂贵的加载过程
    time.Sleep(2 * time.Second)
    
    return &HighResolutionImage{
        filename: filename,
        width:    4000,
        height:   3000,
        data:     make([]byte, 1024*1024*10), // 10MB 模拟数据
    }
}

func (img *HighResolutionImage) Display() {
    fmt.Printf("Displaying high resolution image: %s (%dx%d)\n", 
        img.filename, img.width, img.height)
}

func (img *HighResolutionImage) GetSize() int {
    return len(img.data)
}

// 虚拟代理 - 延迟加载图像
type ImageProxy struct {
    filename string
    realImage *HighResolutionImage
}

func NewImageProxy(filename string) *ImageProxy {
    return &ImageProxy{
        filename: filename,
    }
}

func (proxy *ImageProxy) Display() {
    if proxy.realImage == nil {
        proxy.realImage = NewHighResolutionImage(proxy.filename)
    }
    proxy.realImage.Display()
}

func (proxy *ImageProxy) GetSize() int {
    if proxy.realImage == nil {
        return 0 // 尚未加载
    }
    return proxy.realImage.GetSize()
}

// 保护代理 - 访问控制
type ProtectedImageProxy struct {
    realImage Image
    userRole  string
}

func NewProtectedImageProxy(image Image, userRole string) *ProtectedImageProxy {
    return &ProtectedImageProxy{
        realImage: image,
        userRole:  userRole,
    }
}

func (proxy *ProtectedImageProxy) Display() {
    if !proxy.hasAccess() {
        log.Printf("Access denied for user role: %s", proxy.userRole)
        return
    }
    proxy.realImage.Display()
}

func (proxy *ProtectedImageProxy) GetSize() int {
    if !proxy.hasAccess() {
        return 0
    }
    return proxy.realImage.GetSize()
}

func (proxy *ProtectedImageProxy) hasAccess() bool {
    // 简单的权限检查逻辑
    return proxy.userRole == "admin" || proxy.userRole == "user"
}

// 使用示例
func main() {
    fmt.Println("=== 虚拟代理示例 ===")
    proxy := NewImageProxy("vacation_photo.jpg")
    
    fmt.Println("1. 创建代理,但真实图像尚未加载")
    fmt.Printf("图像大小: %d bytes\n", proxy.GetSize())
    
    fmt.Println("2. 首次显示 - 触发真实图像加载")
    proxy.Display()
    fmt.Printf("图像大小: %d bytes\n", proxy.GetSize())
    
    fmt.Println("\n=== 保护代理示例 ===")
    realImage := NewHighResolutionImage("sensitive_document.jpg")
    
    // 普通用户
    userProxy := NewProtectedImageProxy(realImage, "guest")
    fmt.Println("普通用户尝试访问:")
    userProxy.Display()
    
    // 管理员
    adminProxy := NewProtectedImageProxy(realImage, "admin")
    fmt.Println("管理员尝试访问:")
    adminProxy.Display()
}

🎨 装饰器模式 (Decorator Pattern)

原理介绍

装饰器模式动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

核心思想

  • 透明扩展:在不改变接口的情况下扩展功能
  • 组合优于继承:通过组合而非继承来扩展功能
  • 运行时装饰:可以在运行时动态添加或移除功能

设计方案

go 复制代码
package main

import (
    "fmt"
    "strings"
)

// 组件接口
type DataSource interface {
    Write(data string)
    Read() string
}

// 具体组件
type FileDataSource struct {
    filename string
    content  string
}

func NewFileDataSource(filename string) *FileDataSource {
    return &FileDataSource{
        filename: filename,
    }
}

func (f *FileDataSource) Write(data string) {
    fmt.Printf("Writing to file %s: %s\n", f.filename, data)
    f.content = data
}

func (f *FileDataSource) Read() string {
    fmt.Printf("Reading from file %s: %s\n", f.filename, f.content)
    return f.content
}

// 基础装饰器
type DataSourceDecorator struct {
    wrappee DataSource
}

func NewDataSourceDecorator(source DataSource) *DataSourceDecorator {
    return &DataSourceDecorator{
        wrappee: source,
    }
}

func (d *DataSourceDecorator) Write(data string) {
    d.wrappee.Write(data)
}

func (d *DataSourceDecorator) Read() string {
    return d.wrappee.Read()
}

// 加密装饰器
type EncryptionDecorator struct {
    *DataSourceDecorator
}

func NewEncryptionDecorator(source DataSource) *EncryptionDecorator {
    return &EncryptionDecorator{
        DataSourceDecorator: NewDataSourceDecorator(source),
    }
}

func (e *EncryptionDecorator) Write(data string) {
    encrypted := e.encrypt(data)
    e.DataSourceDecorator.Write(encrypted)
}

func (e *EncryptionDecorator) Read() string {
    encrypted := e.DataSourceDecorator.Read()
    return e.decrypt(encrypted)
}

func (e *EncryptionDecorator) encrypt(data string) string {
    // 简单的加密示例 - 实际应用中应使用真正的加密算法
    result := make([]byte, len(data))
    for i := 0; i < len(data); i++ {
        result[i] = data[i] + 1 // 简单的凯撒密码
    }
    fmt.Printf("加密: %s -> %s\n", data, string(result))
    return string(result)
}

func (e *EncryptionDecorator) decrypt(data string) string {
    result := make([]byte, len(data))
    for i := 0; i < len(data); i++ {
        result[i] = data[i] - 1
    }
    fmt.Printf("解密: %s -> %s\n", data, string(result))
    return string(result)
}

// 压缩装饰器
type CompressionDecorator struct {
    *DataSourceDecorator
}

func NewCompressionDecorator(source DataSource) *CompressionDecorator {
    return &CompressionDecorator{
        DataSourceDecorator: NewDataSourceDecorator(source),
    }
}

func (c *CompressionDecorator) Write(data string) {
    compressed := c.compress(data)
    c.DataSourceDecorator.Write(compressed)
}

func (c *CompressionDecorator) Read() string {
    compressed := c.DataSourceDecorator.Read()
    return c.decompress(compressed)
}

func (c *CompressionDecorator) compress(data string) string {
    // 简单的压缩示例 - 运行长度编码
    var result strings.Builder
    count := 1
    for i := 1; i <= len(data); i++ {
        if i < len(data) && data[i] == data[i-1] {
            count++
        } else {
            result.WriteByte(data[i-1])
            fmt.Fprintf(&result, "%d", count)
            count = 1
        }
    }
    fmt.Printf("压缩: %s -> %s\n", data, result.String())
    return result.String()
}

func (c *CompressionDecorator) decompress(data string) string {
    // 简单的解压缩
    var result strings.Builder
    i := 0
    for i < len(data) {
        char := data[i]
        i++
        count := 0
        for i < len(data) && data[i] >= '0' && data[i] <= '9' {
            count = count*10 + int(data[i]-'0')
            i++
        }
        for j := 0; j < count; j++ {
            result.WriteByte(char)
        }
    }
    fmt.Printf("解压缩: %s -> %s\n", data, result.String())
    return result.String()
}

// 使用示例
func main() {
    fmt.Println("=== 基础文件操作 ===")
    file := NewFileDataSource("test.txt")
    file.Write("Hello, World!")
    fmt.Printf("读取: %s\n\n", file.Read())
    
    fmt.Println("=== 加密文件操作 ===")
    encryptedFile := NewEncryptionDecorator(file)
    encryptedFile.Write("Sensitive Data")
    fmt.Printf("读取: %s\n\n", encryptedFile.Read())
    
    fmt.Println("=== 压缩文件操作 ===")
    compressedFile := NewCompressionDecorator(file)
    compressedFile.Write("AAAAABBBCCCDDE")
    fmt.Printf("读取: %s\n\n", compressedFile.Read())
    
    fmt.Println("=== 加密+压缩组合 ===")
    superFile := NewEncryptionDecorator(
        NewCompressionDecorator(
            NewFileDataSource("super.txt"),
        ),
    )
    superFile.Write("Top Secret Message")
    fmt.Printf("读取: %s\n", superFile.Read())
}

🔄 适配器模式 (Adapter Pattern)

原理介绍

适配器模式将一个类的接口转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。

核心思想

  • 接口转换:将不兼容的接口转换为目标接口
  • 桥接功能:在不同接口之间建立桥梁
  • 复用现有代码:无需修改现有代码即可集成新功能

设计方案

go 复制代码
package main

import (
    "fmt"
    "strconv"
)

// 目标接口 - 现代支付系统期望的接口
type ModernPaymentGateway interface {
    ProcessPayment(amount float64, currency string) (string, error)
    Refund(transactionID string) (string, error)
}

// 适配者 - 遗留的支付系统
type LegacyPaymentSystem struct{}

func (l *LegacyPaymentSystem) MakePayment(amountInCents int, currencyCode string) (int, string) {
    fmt.Printf("Legacy system: Processing payment of %d cents in %s\n", amountInCents, currencyCode)
    // 模拟处理逻辑
    transactionID := 12345
    return transactionID, "SUCCESS"
}

func (l *LegacyPaymentSystem) CancelPayment(transactionID int) string {
    fmt.Printf("Legacy system: Cancelling transaction %d\n", transactionID)
    return "REFUNDED"
}

func (l *LegacyPaymentSystem) ValidateCurrency(currencyCode string) bool {
    supportedCurrencies := map[string]bool{
        "USD": true, "EUR": true, "GBP": true,
    }
    return supportedCurrencies[currencyCode]
}

// 适配器 - 将遗留系统适配到现代接口
type LegacyPaymentAdapter struct {
    legacySystem *LegacyPaymentSystem
}

func NewLegacyPaymentAdapter() *LegacyPaymentAdapter {
    return &LegacyPaymentAdapter{
        legacySystem: &LegacyPaymentSystem{},
    }
}

func (a *LegacyPaymentAdapter) ProcessPayment(amount float64, currency string) (string, error) {
    // 转换金额格式:美元转分
    amountInCents := int(amount * 100)
    
    // 验证货币
    if !a.legacySystem.ValidateCurrency(currency) {
        return "", fmt.Errorf("unsupported currency: %s", currency)
    }
    
    // 调用遗留系统
    transactionID, status := a.legacySystem.MakePayment(amountInCents, currency)
    
    if status != "SUCCESS" {
        return "", fmt.Errorf("payment failed with status: %s", status)
    }
    
    return fmt.Sprintf("TXN-%d", transactionID), nil
}

func (a *LegacyPaymentAdapter) Refund(transactionID string) (string, error) {
    // 解析交易ID
    if len(transactionID) <= 4 {
        return "", fmt.Errorf("invalid transaction ID: %s", transactionID)
    }
    
    idStr := transactionID[4:] // 去掉 "TXN-" 前缀
    id, err := strconv.Atoi(idStr)
    if err != nil {
        return "", fmt.Errorf("invalid transaction ID format: %s", transactionID)
    }
    
    // 调用遗留系统
    status := a.legacySystem.CancelPayment(id)
    
    if status != "REFUNDED" {
        return "", fmt.Errorf("refund failed with status: %s", status)
    }
    
    return fmt.Sprintf("REFUND-%s", transactionID), nil
}

// 另一个适配者示例 - 第三方支付服务
type ThirdPartyPaymentService struct{}

func (t *ThirdPartyPaymentService) Pay(amount float64, currency string, options map[string]interface{}) map[string]interface{} {
    fmt.Printf("ThirdParty: Processing payment of %.2f %s\n", amount, currency)
    return map[string]interface{}{
        "success":      true,
        "payment_id":   "TP-" + fmt.Sprintf("%d", 67890),
        "status":       "completed",
        "fee_amount":   amount * 0.029, // 2.9% 手续费
    }
}

func (t *ThirdPartyPaymentService) ReversePayment(paymentID string) map[string]interface{} {
    fmt.Printf("ThirdParty: Reversing payment %s\n", paymentID)
    return map[string]interface{}{
        "success": true,
        "refund_id": "REF-" + paymentID,
    }
}

// 第三方支付适配器
type ThirdPartyPaymentAdapter struct {
    thirdPartyService *ThirdPartyPaymentService
}

func NewThirdPartyPaymentAdapter() *ThirdPartyPaymentAdapter {
    return &ThirdPartyPaymentAdapter{
        thirdPartyService: &ThirdPartyPaymentService{},
    }
}

func (a *ThirdPartyPaymentAdapter) ProcessPayment(amount float64, currency string) (string, error) {
    result := a.thirdPartyService.Pay(amount, currency, nil)
    
    if !result["success"].(bool) {
        return "", fmt.Errorf("third party payment failed")
    }
    
    return result["payment_id"].(string), nil
}

func (a *ThirdPartyPaymentAdapter) Refund(transactionID string) (string, error) {
    result := a.thirdPartyService.ReversePayment(transactionID)
    
    if !result["success"].(bool) {
        return "", fmt.Errorf("third party refund failed")
    }
    
    return result["refund_id"].(string), nil
}

// 支付处理器 - 使用统一的现代接口
type PaymentProcessor struct {
    gateway ModernPaymentGateway
}

func NewPaymentProcessor(gateway ModernPaymentGateway) *PaymentProcessor {
    return &PaymentProcessor{
        gateway: gateway,
    }
}

func (p *PaymentProcessor) MakePayment(amount float64, currency string) {
    fmt.Printf("\n处理支付: %.2f %s\n", amount, currency)
    
    transactionID, err := p.gateway.ProcessPayment(amount, currency)
    if err != nil {
        fmt.Printf("支付失败: %v\n", err)
        return
    }
    
    fmt.Printf("支付成功! 交易ID: %s\n", transactionID)
}

func (p *PaymentProcessor) ProcessRefund(transactionID string) {
    fmt.Printf("\n处理退款: %s\n", transactionID)
    
    refundID, err := p.gateway.Refund(transactionID)
    if err != nil {
        fmt.Printf("退款失败: %v\n", err)
        return
    }
    
    fmt.Printf("退款成功! 退款ID: %s\n", refundID)
}

// 使用示例
func main() {
    fmt.Println("=== 遗留支付系统适配器 ===")
    legacyAdapter := NewLegacyPaymentAdapter()
    processor1 := NewPaymentProcessor(legacyAdapter)
    
    processor1.MakePayment(99.99, "USD")
    processor1.ProcessRefund("TXN-12345")
    
    fmt.Println("\n=== 第三方支付适配器 ===")
    thirdPartyAdapter := NewThirdPartyPaymentAdapter()
    processor2 := NewPaymentProcessor(thirdPartyAdapter)
    
    processor2.MakePayment(49.99, "EUR")
    processor2.ProcessRefund("TP-67890")
    
    // 测试错误情况
    fmt.Println("\n=== 错误处理测试 ===")
    processor1.MakePayment(100.00, "JPY") // 不支持的货币
    processor1.ProcessRefund("INVALID-ID") // 无效的交易ID
}

🏢 外观模式 (Facade Pattern)

原理介绍

外观模式为子系统中的一组接口提供一个统一的高层接口。外观模式定义了一个更高级的接口,使得子系统更容易使用。

核心思想

  • 简化接口:提供简单的接口来隐藏子系统的复杂性
  • 解耦:将客户端与子系统解耦
  • 统一入口:为复杂的子系统提供统一的访问点

设计方案

go 复制代码
package main

import (
    "fmt"
    "log"
)

// 复杂的子系统 - 视频转换系统

// 视频编解码器
type VideoCodec interface {
    Decode(file []byte) []byte
    Encode(data []byte) []byte
}

type H264Codec struct{}

func (h *H264Codec) Decode(file []byte) []byte {
    fmt.Println("H264: 解码视频文件")
    return []byte("解码后的原始数据")
}

func (h *H264Codec) Encode(data []byte) []byte {
    fmt.Println("H264: 编码视频数据")
    return []byte("H264编码的视频数据")
}

type VP9Codec struct{}

func (v *VP9Codec) Decode(file []byte) []byte {
    fmt.Println("VP9: 解码视频文件")
    return []byte("解码后的原始数据")
}

func (v *VP9Codec) Encode(data []byte) []byte {
    fmt.Println("VP9: 编码视频数据")
    return []byte("VP9编码的视频数据")
}

// 音频处理系统
type AudioProcessor struct{}

func (a *AudioProcessor) ExtractAudio(videoData []byte) []byte {
    fmt.Println("音频处理: 从视频中提取音频")
    return []byte("提取的音频数据")
}

func (a *AudioProcessor) NormalizeAudio(audioData []byte) []byte {
    fmt.Println("音频处理: 标准化音频")
    return []byte("标准化后的音频数据")
}

func (a *AudioProcessor) MixAudio(audio1, audio2 []byte) []byte {
    fmt.Println("音频处理: 混合音频轨道")
    return []byte("混合后的音频数据")
}

// 视频处理系统
type VideoProcessor struct{}

func (v *VideoProcessor) ResizeVideo(data []byte, width, height int) []byte {
    fmt.Printf("视频处理: 调整分辨率 %dx%d\n", width, height)
    return data
}

func (v *VideoProcessor) ApplyFilter(data []byte, filter string) []byte {
    fmt.Printf("视频处理: 应用滤镜 '%s'\n", filter)
    return data
}

func (v *VideoProcessor) AdjustBitrate(data []byte, bitrate int) []byte {
    fmt.Printf("视频处理: 调整码率 %d kbps\n", bitrate)
    return data
}

// 文件输出系统
type FileOutputSystem struct{}

func (f *FileOutputSystem) CreateFile(filename string) {
    fmt.Printf("文件输出: 创建文件 %s\n", filename)
}

func (f *FileOutputSystem) WriteData(data []byte) {
    fmt.Printf("文件输出: 写入数据 (%d bytes)\n", len(data))
}

func (f *FileOutputSystem) CloseFile() {
    fmt.Println("文件输出: 关闭文件")
}

// 质量检查系统
type QualityControl struct{}

func (q *QualityControl) CheckVideoQuality(data []byte) bool {
    fmt.Println("质量检查: 检查视频质量")
    return true
}

func (q *QualityControl) CheckAudioSync(videoData, audioData []byte) bool {
    fmt.Println("质量检查: 检查音视频同步")
    return true
}

func (q *QualityControl) GenerateReport() string {
    fmt.Println("质量检查: 生成质量报告")
    return "质量检查报告: 所有检查通过"
}

// 外观类 - 视频转换外观
type VideoConversionFacade struct {
    h264Codec        *H264Codec
    vp9Codec         *VP9Codec
    audioProcessor   *AudioProcessor
    videoProcessor   *VideoProcessor
    fileOutput       *FileOutputSystem
    qualityControl   *QualityControl
}

func NewVideoConversionFacade() *VideoConversionFacade {
    return &VideoConversionFacade{
        h264Codec:      &H264Codec{},
        vp9Codec:       &VP9Codec{},
        audioProcessor: &AudioProcessor{},
        videoProcessor: &VideoProcessor{},
        fileOutput:     &FileOutputSystem{},
        qualityControl: &QualityControl{},
    }
}

// 简化后的高级接口
func (f *VideoConversionFacade) ConvertVideoSimple(inputFile []byte, outputFormat string) error {
    fmt.Printf("开始视频转换: %s 格式\n", outputFormat)
    fmt.Println("==================================")
    
    var codec VideoCodec
    switch outputFormat {
    case "h264":
        codec = f.h264Codec
    case "vp9":
        codec = f.vp9Codec
    default:
        return fmt.Errorf("不支持的格式: %s", outputFormat)
    }
    
    // 解码原始视频
    rawVideo := codec.Decode(inputFile)
    
    // 处理视频
    processedVideo := f.videoProcessor.ResizeVideo(rawVideo, 1920, 1080)
    processedVideo = f.videoProcessor.ApplyFilter(processedVideo, "contrast")
    
    // 处理音频
    audioData := f.audioProcessor.ExtractAudio(rawVideo)
    audioData = f.audioProcessor.NormalizeAudio(audioData)
    
    // 编码最终视频
    finalVideo := codec.Encode(processedVideo)
    
    // 质量检查
    if !f.qualityControl.CheckVideoQuality(finalVideo) {
        return fmt.Errorf("视频质量检查失败")
    }
    if !f.qualityControl.CheckAudioSync(finalVideo, audioData) {
        return fmt.Errorf("音视频同步检查失败")
    }
    
    // 输出文件
    f.fileOutput.CreateFile("output." + outputFormat)
    f.fileOutput.WriteData(finalVideo)
    f.fileOutput.CloseFile()
    
    report := f.qualityControl.GenerateReport()
    fmt.Printf("转换完成: %s\n", report)
    fmt.Println("==================================")
    
    return nil
}

func (f *VideoConversionFacade) ConvertForWeb(inputFile []byte, quality string) error {
    fmt.Printf("开始Web视频转换: %s 质量\n", quality)
    fmt.Println("==================================")
    
    var width, height, bitrate int
    switch quality {
    case "low":
        width, height, bitrate = 640, 360, 500
    case "medium":
        width, height, bitrate = 1280, 720, 1500
    case "high":
        width, height, bitrate = 1920, 1080, 4000
    default:
        return fmt.Errorf("不支持的质量级别: %s", quality)
    }
    
    // 使用 VP9 编码器进行Web优化
    rawVideo := f.vp9Codec.Decode(inputFile)
    
    // 视频处理
    processedVideo := f.videoProcessor.ResizeVideo(rawVideo, width, height)
    processedVideo = f.videoProcessor.AdjustBitrate(processedVideo, bitrate)
    
    // 音频处理
    audioData := f.audioProcessor.ExtractAudio(rawVideo)
    audioData = f.audioProcessor.NormalizeAudio(audioData)
    
    // 编码
    finalVideo := f.vp9Codec.Encode(processedVideo)
    
    // 质量检查
    f.qualityControl.CheckVideoQuality(finalVideo)
    
    // 输出
    f.fileOutput.CreateFile(fmt.Sprintf("web_%s_quality.vp9", quality))
    f.fileOutput.WriteData(finalVideo)
    f.fileOutput.CloseFile()
    
    fmt.Println("Web视频转换完成!")
    fmt.Println("==================================")
    
    return nil
}

func (f *VideoConversionFacade) ExtractAudioOnly(inputFile []byte, outputFormat string) error {
    fmt.Printf("提取音频: %s 格式\n", outputFormat)
    fmt.Println("==================================")
    
    // 解码视频
    rawVideo := f.h264Codec.Decode(inputFile)
    
    // 提取和处理音频
    audioData := f.audioProcessor.ExtractAudio(rawVideo)
    audioData = f.audioProcessor.NormalizeAudio(audioData)
    
    // 输出音频文件
    f.fileOutput.CreateFile("audio_only." + outputFormat)
    f.fileOutput.WriteData(audioData)
    f.fileOutput.CloseFile()
    
    fmt.Println("音频提取完成!")
    fmt.Println("==================================")
    
    return nil
}

// 使用示例
func main() {
    facade := NewVideoConversionFacade()
    
    // 模拟输入文件数据
    inputVideo := []byte("模拟视频文件数据")
    
    fmt.Println("🎬 视频转换系统演示")
    fmt.Println("==================")
    
    // 简单转换
    err := facade.ConvertVideoSimple(inputVideo, "h264")
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Println()
    
    // Web优化转换
    err = facade.ConvertForWeb(inputVideo, "medium")
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Println()
    
    // 仅提取音频
    err = facade.ExtractAudioOnly(inputVideo, "mp3")
    if err != nil {
        log.Fatal(err)
    }
}

📊 模式对比总结

模式 目的 适用场景 Go 实现特点
代理模式 控制访问,延迟加载 权限控制、缓存、虚拟代理 接口实现,组合代替继承
装饰器模式 动态添加功能 功能扩展,不修改原代码 接口嵌入,多层装饰
适配器模式 接口转换 集成遗留代码,第三方库适配 实现目标接口,包装适配者
外观模式 简化复杂系统 子系统封装,提供统一接口 结构体组合,简化方法

🎯 最佳实践建议

  1. 接口设计:优先定义简洁清晰的接口
  2. 组合优于继承:充分利用 Go 的组合特性
  3. 单一职责:每个模式专注于单一目的
  4. 错误处理:在适配器和外观中妥善处理错误
  5. 测试友好:通过接口使得模式易于测试
相关推荐
闲人编程1 小时前
Python的抽象基类(ABC):定义接口契约的艺术
开发语言·python·接口·抽象类·基类·abc·codecapsule
lkbhua莱克瓦242 小时前
集合进阶8——Stream流
java·开发语言·笔记·github·stream流·学习方法·集合
20岁30年经验的码农2 小时前
Java Elasticsearch 实战指南
java·开发语言·elasticsearch
雾岛听蓝2 小时前
C++ 类和对象(一):从概念到实践,吃透类的核心基础
开发语言·c++·经验分享·笔记
CoderYanger2 小时前
优选算法-优先级队列(堆):75.数据流中的第K大元素
java·开发语言·算法·leetcode·职场和发展·1024程序员节
TracyCoder1233 小时前
MySQL 实战宝典(八):Java后端MySQL分库分表工具解析与选型秘籍
java·开发语言·mysql
非凡的世界3 小时前
为什么我和越来越多的PHP程序员,选择了 Webman ?
开发语言·php·workman·webman
MarkHD3 小时前
车辆TBOX科普 第45次
java·开发语言
还债大湿兄3 小时前
阿里通义千问调用图像大模型生成轮动漫风格 python调用
开发语言·前端·python