尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

代码开发,常用的几种设计模式【golang】

代码开发,常用的几种设计模式【golang】
📅 发布时间:2026/6/20 15:08:00

一、创建型模式(处理对象创建)

1. 单例模式(Singleton)

用途:保证一个结构体在程序运行期间只有一个实例(确保全局只有一个实例被new出来),并提供全局访问点(如配置管理器、日志器)

Go 实现特点:利用 sync.Once 保证线程安全,是 Go 中最优雅的单例实现方式

读取配置文件案例

var(instance*Config once sync.Once)funcGetConfig()*Config{once.Do(func(){instance=&Config{Port:8080}})returninstance}
2. 工厂模式(Factory)

用途:封装对象创建逻辑,根据不同条件返回不同的结构体实例

Go 实现特点:通常用函数返回接口。

获取不同类型数据库链接句柄

typeDBinterface{Query(string)string}typeMySQLstruct{}func(m MySQL)Query(qstring)string{return"MySQL: "+q}typePgSQLstruct{}func(m PgSQL)Query(qstring)string{return"PgSQL: "+q}// 工厂函数funcNewDB(dbTypestring)DB{switchdbType{case"mysql":returnMySQL{}case"pgsql":returnPgSQL{}default:panic("unsupported db")}}

二、结构型模式(处理对象组合)

1. 装饰器模式(Decorator)

装饰器模式(Decorator Pattern)是一种结构型设计模式,核心目标是:在不修改原有对象代码的前提下,动态地给对象添加额外的功能。

用途:动态添加功能(如日志、限流、认证)

Go 实现特点:体现有多种,如函数嵌套、组合 + 接口方式继承重写方法等

标准库http服务实现案例

funcmain(){http.HandleFunc("/api",myHandler)http.ListenAndServe(":8080",nil)}// 业务逻辑funcmyHandler(w http.ResponseWriter,r*http.Request){w.WriteHeader(http.StatusOK)w.Write([]byte("Hello from decorated handler!"))// ……}

这是标准库的内置方法,http.HandleFunc定义为func HandleFunc(pattern string, handler func(ResponseWriter, *Request))

现在我要给我的业务逻辑方法加个日志,又不想改动其代码,现在给它包裹上一层

funcmain(){handler:=withLogging(myHandler)http.HandleFunc("/api",handler)http.ListenAndServe(":8080",nil)}funcwithLogging(next http.HandlerFunc)http.HandlerFunc{returnfunc(w http.ResponseWriter,r*http.Request){log.Printf("Received request: %s %s",r.Method,r.URL.Path)next(w,r)// 这里是业务逻辑方法}}// 业务逻辑funcmyHandler(w http.ResponseWriter,r*http.Request){w.WriteHeader(http.StatusOK)w.Write([]byte("Hello from decorated handler!"))}

通过重新定义一个闭包函数,加点日志代码,对其原有业务逻辑进行装饰

另一种继承式写法,计算咖啡价格

// 咖啡typeCoffeeinterface{Cost()int// 价格}// 接口实现:咖啡价格typeBlackCoffeestruct{}func(b*BlackCoffee)Cost()int{return10}// 装饰器1:咖啡加牛奶的价格typeMilkDecoratorstruct{coffee Coffee// 嵌套咖啡接口}func(m*MilkDecorator)Cost()int{returnm.coffee.Cost()+2// 基础价格+牛奶价格}// 传入实现Coffee接口的实例,返回另一个实现Coffee接口的实例funcNewMilkDecorator(coffee Coffee)Coffee{return&MilkDecorator{coffee:coffee}}funcmain(){// 基础黑咖啡coffee:=&BlackCoffee{}fmt.Printf("价格:%d\n",coffee.Cost())// 价格:10// 加牛奶(装饰)coffeeWithMilk:=NewMilkDecorator(coffee)fmt.Printf("价格:%d\n",coffeeWithMilk.Cost())// 黑咖啡 + 牛奶, 价格:12}
2. 适配器模式(Adapter)

用途:将一个结构体的接口转换成客户端期望的另一个接口,解决接口不兼容问题

Go 实现特点:适配器结构体嵌套原结构体,实现目标接口

继承老的业务逻辑,新增新的接口实现

// 旧的代码定义typeOldhandlestruct{}func(a*Oldhandle)SpecificRequest()string{return"旧接口的具体实现"}// 现在感觉 SpecificRequest 名字不好听,改成 Request// 希望的接口定义typeTargetinterface{Request()string}// 适配器:将 Oldhandle 适配为Target接口typeNewHandlestruct{Oldhandle*Oldhandle}// 实现 Target 接口,内部调用 Oldhandle 的方法func(a*NewHandle)Request()string{return"适配后:"+a.Oldhandle.SpecificRequest()}funcmain(){// 客户端只依赖 Target 接口,无需关心 Oldhandle 的具体实现vartarget Target=&NewHandle{Oldhandle:&Oldhandle{}}target.Request()// 输出: 适配后:旧接口的具体实现}

装饰器与适配器非常类似,几乎没什么不同,通过类型嵌套方式继承功能并改造

三、行为型模式(处理对象交互)

1. 策略模式(Strategy)

用途:定义一系列算法,将每个算法封装起来并可互相替换,使算法独立于使用它的客户端(如支付方式、排序算法切换)。

Go 实现特点:通过接口定义算法行为,不同策略实现该接口,客户端动态切换策略。

微信支付、支付宝支付,业务逻辑选择

// 1. 支付接口定义(策略定义)typePayInterinterface{Pay(amountfloat64)string// 输入金额,返回支付结果}// 2. 策略可选列表// 2.1 支付宝typeAlipaystruct{}func(a Alipay)Pay(amountfloat64)string{returnfmt.Sprintf("Paid %.2f via Alipay",amount)}// 2.2 微信支付typeWechatPaystruct{}func(w WechatPay)Pay(amountfloat64)string{returnfmt.Sprintf("Paid %.2f via WeChat",amount)}// 3. 策略执行// 购物车支付场景typeShoppingCartstruct{payMethod PayInter}// 设置购物车支付场景用哪种方式支付func(cart*ShoppingCart)SetPayMethod(method PayInter){cart.payMethod=method}// 执行支付func(cart*ShoppingCart)Checkout(amountfloat64)string{ifcart.payMethod==nil{return"No payment method set"}returncart.payMethod.Pay(amount)}funcmain(){cart:=&ShoppingCart{}cart.SetPayMethod(Alipay{})fmt.Println(cart.Checkout(99.9))// Paid 99.90 via Alipaycart.SetPayMethod(WechatPay{})fmt.Println(cart.Checkout(199.0))// Paid 199.00 via WeChat}

这种方式本质上还是结构体嵌套,继承

2. 选项模式

用途:优雅地设置可选参数(替代构造函数重载)

广泛用于代码量大的类库封装(如 http.Server, grpc.DialOption)

初始化一个结构体示例

typeServerstruct{PortintTimeout time.Duration}funcNewServer(portint,timeout time.Duration)*Server{return&Server{Port:port,Timeout:timeout,}}funcTestManual(t*testing.T){server:=NewServer(3000,5*time.Second)t.Log(server.Port)}

通过NewServer方法初始化Server结构,Server的参数有十几个,NewServer里面的参数定义要写很多,不美观,比方说

NewServer(port int, timeout time.Duration, worker int)我现在调用NewServer方法时,只想设置port和worker参数,中间这个参数我还得想办法传递个零值或默认值进去,不然代码会报错

现在换一种写法,通过增加代码量来提升维护性

typeServerstruct{PortintTimeout time.Duration}typeOptionfunc(*Server)funcWithPort(portint)Option{returnfunc(s*Server){s.Port=port}}funcWithTimeout(t time.Duration)Option{returnfunc(s*Server){s.Timeout=t}}funcNewServer(opts...Option)*Server{s:=&Server{Port:8080}for_,opt:=rangeopts{opt(s)}returns}// 业务逻辑funcTestManual(t*testing.T){server:=NewServer(WithPort(3000),WithTimeout(5*time.Second))t.Log(server.Port)}

现在调用NewServer方法时,想自定义哪个参数,就传递指定配置方法即可,也不用操心顺序,反正是个切片类型

四、管道/过滤器模式(Pipeline / Filter)

用途:通过 channel 串联处理步骤(典型 Go 并发模式)

基于 goroutine + channel

我习惯称之为一个小的MapReduce实现

// 这里生产数据,预处理funcgen(nums...int)<-chanint{out:=make(chanint)gofunc(){for_,n:=rangenums{out<-n}close(out)}()returnout}// 这里加工数据funcsq(in<-chanint)<-chanint{out:=make(chanint)gofunc(){forn:=rangein{out<-n*n}close(out)}()returnout}// 这里通过range读取chan展示数据funcmain(){forn:=rangesq(gen(1,2,3)){fmt.Println(n)}}

剩下的还有观察者模式等等一大堆写法,总的来说无非都是闭包、结构体继承、chan读写等……

相关新闻

  • ChatGPT分不清1062?AI Agent2.0已来临!四大核心组件让大模型真正‘活‘起来,小白程序员必学!
  • LoongSuite:解决 WebSocket 全链路可观测性难题,赋能 AI 应用的实时链路追踪
  • 国际版JAVA任务系统:多端互通,接单无忧

最新新闻

  • 2026 国内美妆护肤包装设计公司 TOP 榜单|靠谱美妆包装定制机构推荐 - 宏洛图品牌设计
  • Web UI 自动化测试 Skill 完整实战:从一个空项目到一份中文测试报告
  • 3步搞定B站抢票难题:biliTickerBuy终极使用指南
  • 2026效率榜!好用的降AIGC工具实测,效率直接拉满!
  • 2026年10款论文降AIGC网站亲测:从90%降至10%的宝藏之选 - 降AI小能手
  • 南京想买宠物?这8家门店环境和服务都值得参考 - 园友3800037

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号