OOP
但是 Go 语言下没有类(Class), 没有 指针, 没有多态, 只有复合.
应用 OOP 的思想, WEB 应用下控制器常见形式祖先类型的写法(示意代码).
虽然 Go 只有复合, 但这并不妨碍实现类似 OOP 继承的方式.Login
这样用
http.Handle("/login", &Login{})
但是很明显,现实中这样的用法是错误的, 因为 WEB 的请求是并发的, 这样写所有并发的请求都由同一个&Login{}
去处理.Req
,Res
,Data
会在并发中被重复赋值.
我们需要对每一个请求都及时生成一个 Login
对象的机制.
这个http.Handler
接口其实只是被当作一个函数使用了. 并发问题留给使用者自己解决.
对于这种在属性中有数据设置的复合结构. 需要在并发下及时生成新对象.
HandlerFunc
的工作方式就是我们要的, 可以这样做
http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
p := &Login{}
})
每次请求都有新的Login
对象产生. 当然这个写法很生硬, 如果有100个控制器,难道还要写100个不同的写法! 多数 WEB 框架会通过反射包的支持, 构建新对象. 的确是个好方法. 这种方法, 这里不打算费笔墨介绍.
函数
这是一种看上去蛋疼的用法.
构造函数
Go 没有构造函数的概念的. 没关系我们模拟一个. 一般构造用Constructor
, 这里选用 New
更符合 Go 代码风格.
// 给控制器接口增加一个构造函数
New() HttpPostController
ServeHTTP(w http.ResponseWriter, r *http.Request)
Post()
Out()
}
// 扩充 Login , 实现 HttpPostController 接口
return &Login{}
// 需要一个能配合 http.Handler 支持构造函数
type HandlerNew struct {
Constructor HttpPostController
}
// http.Handler 接口实现
func (p HandlerNew) ServeHTTP(w http.ResponseWriter, r *http.Request) {
c := p.Constructor.New()
}
这样使用
其实就是一层层的 接口包裹起来.
谁知道呢
闭包和构造函数的方法, 什么时候用? 我只是把他们罗列出来, 我不知道什么样的场景可以用到. 或许后续的实现中就会用到, 或许用的时候改变一些代码和参数就变的很好使, 谁知道呢!