1.回顾
前面我们已经对SimpleWeb进行了改造,已经解决了原本SimpleWeb中ServeHttp中路由映射规则以及业务逻辑耦合在一起的问题,也方便了路由映射规则的扩展。
但是此处还存在一个问题,我们看下前面的例子
type HelloHandler struct {
}
func (handler *HelloHandler) ServeHttp(c *Conn, req *Request) {
c.WriteData([]byte("hello"))
}
func main() {
// 创建一个处理器
router := SimpleWeb{routes: map[string]Handler{}}
// 完成请求和处理器的映射关系
router.SetRoute("/hello", &HelloHandler{})
// 启动http服务器
ListenAndServe(":8080", &router)
}
这里我们创建一个HTTP服务器,此处需要给/hello 的请求设置一个请求处理器,请求处理器需要实现Handler接口,此处需要定义一个结构体HelloHandler,由其实现Handler接口。
那我们想一下,如果现在有一百个不同的请求路径,那么此时就存在一百个请求处理器,那么是不是需要创建100个结构体,然后实现一百次该接口。
2.改进
首先,定义HandleFunc类型,函数也是能够作为一种类型,实现Handler接口
type HandleFunc func(conn *Conn, request *Request)
func (f HandleFunc) ServeHttp(c *Conn, r *Request) {
f(c, r)
}
接着,修改前面例子中的HTTP服务器,此时不再需要定义结构体,直接编写业务逻辑函数,比如下面的HandlerHello,将其强制类型转换为HandleFunc类型。
因为HandleFunc类型已经实现了Handler接口,所以可以作为SetRoute的参数,完成路由匹配规则的注册。
func HandlerHello(c *Conn, req *Request) {
c.WriteData([]byte("hello"))
}
func main() {
router := SimpleWeb{routes: map[string]Handler{}}
router.SetRoute("/hello", HandleFunc(HandlerHello))
ListenAndServe(":8080", &router)
}
这样子就不需要每个HTTP处理器都去创建一个结构体,然后实现Handler接口。