OOP

但是 Go 语言下没有类(Class), 没有 指针, 没有多态, 只有复合.

应用 OOP 的思想, WEB 应用下控制器常见形式祖先类型的写法(示意代码).

虽然 Go 只有复合, 但这并不妨碍实现类似 OOP 继承的方式.
Login 这样用

  1. http.Handle("/login", &Login{})

但是很明显,现实中这样的用法是错误的, 因为 WEB 的请求是并发的, 这样写所有并发的请求都由同一个&Login{}去处理.
Req,Res,Data 会在并发中被重复赋值.
我们需要对每一个请求都及时生成一个 Login 对象的机制.

这个http.Handler接口其实只是被当作一个函数使用了. 并发问题留给使用者自己解决.
对于这种在属性中有数据设置的复合结构. 需要在并发下及时生成新对象.

HandlerFunc的工作方式就是我们要的, 可以这样做

  1. http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
  2. p := &Login{}
  3. })

每次请求都有新的Login对象产生. 当然这个写法很生硬, 如果有100个控制器,难道还要写100个不同的写法! 多数 WEB 框架会通过反射包的支持, 构建新对象. 的确是个好方法. 这种方法, 这里不打算费笔墨介绍.

函数

这是一种看上去蛋疼的用法.

构造函数

Go 没有构造函数的概念的. 没关系我们模拟一个. 一般构造用Constructor, 这里选用 New 更符合 Go 代码风格.

  1. // 给控制器接口增加一个构造函数
  2. New() HttpPostController
  3. ServeHTTP(w http.ResponseWriter, r *http.Request)
  4. Post()
  5. Out()
  6. }
  7. // 扩充 Login , 实现 HttpPostController 接口
  8. return &Login{}
  9. // 需要一个能配合 http.Handler 支持构造函数
  10. type HandlerNew struct {
  11. Constructor HttpPostController
  12. }
  13. // http.Handler 接口实现
  14. func (p HandlerNew) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  15. c := p.Constructor.New()
  16. }

这样使用

其实就是一层层的 接口包裹起来.

谁知道呢

闭包和构造函数的方法, 什么时候用? 我只是把他们罗列出来, 我不知道什么样的场景可以用到. 或许后续的实现中就会用到, 或许用的时候改变一些代码和参数就变的很好使, 谁知道呢!