Factory 和 Strategy 模式用于解耦对象创建与行为逻辑,避免硬编码导致的扩展困难;interface{} 易引发 panic,应使用强类型 key;embed+template 结合 Template Method 实现可覆盖的默认页面;middleware 链优先用 slice,因实际项目中数量少且插入/删除极少。

为什么框架里总在用 Factory 和 Strategy 而不是硬编码
因为框架必须应对用户千差万别的实现方式,硬编码 NewHTTPServer() 或 HandleJSON() 会让扩展变成改源码。Factory 模式把对象创建逻辑收口到接口(如 ServerBuilder),Strategy 则让路由匹配、中间件执行这些可变行为变成可插拔的策略。比如 Gin 的 gin.Engine.Use() 实际注册的是 func(*gin.Context) 类型的策略函数,而不是写死某一种日志或鉴权逻辑。
Interface{} 在 Adapter 模式中容易引发 panic 的真实场景
很多框架用 interface{} 做通用参数(如 context.WithValue(ctx, key, value)),但一旦类型断言失败就 panic。典型踩坑点:传入 int64 却用 v.(int) 断言;或 key 用字符串字面量导致不同包里同名 key 冲突。解决方法是定义强类型 key,比如 type userIDKey struct{},再用 ctx.Value(userIDKey{}).(int64) —— 编译期能检查,运行时不会因 key 类型错乱而丢数据。
Go 的 embed + template 与 Template Method 模式的结合实践
框架常需提供默认 HTML 页面(如 404、健康检查页),又允许用户覆盖。这时不能靠继承(Go 没类继承),而是用 Template Method 思路:定义执行骨架(RenderPage(ctx, name string)),内部调用可重写的 getTemplate(name string) (*template.Template, error)。配合 //go:embed templates/* 把默认模板编译进二进制,用户只需实现自己的 getTemplate 返回自定义模板即可。关键点:template.ParseFS() 要处理嵌套目录,且 FuncMap 必须提前注入,否则运行时报 function "xxx" not defined。
模板采用响应式设计,自动适应手机,电脑及平板显示;满足单一店铺外卖需求。功能:1.菜单分类管理2.菜品管理:菜品增加,删除,修改3.订单管理4.友情链接管理5.数据库备份6.文章模块:如:促销活动,帮助中心7.单页模块:如:企业信息,关于我们更强大的功能在开发中……安装方法:上传到网站根目录,运行http://www.***.com/install 自动
func (s *Server) getTemplate(name string) (*template.Template, error) {
if s.customTemplates != nil {
return s.customTemplates.Lookup(name), nil
}
return template.New("").Funcs(s.funcMap).ParseFS(embeddedFiles, "templates/*")
}
Middleware 链里用链表结构而非 slice 的性能取舍
像 Echo 或 Gin 用 slice 存 middleware([]func(Context)),追加快但中间插入/删除慢;而某些自研框架用双向链表(*middlewareNode)支持动态插拔。实际项目中,middleware 数量通常 []byte,可能阻止 GC 回收,导致内存持续增长。
立即学习“go语言免费学习笔记(深入)”;
框架里设计模式的价值不在“用了多少种”,而在是否让某处修改不影响其他模块。最常被忽略的是:模式本身会增加间接层,当 handler 只有三行代码时,硬套 Observer 或 Visitor 反而让问题更难定位。









