我们利用全静态匹配来构建路由树,后面再考虑重构路由树以支持通配符匹配、参数路由等复杂匹配
所谓的静态匹配,就是路径的每一段都必须严格相等
这里我们按照上节课说的,设计一种比较符合常规认知的路由树.
如同Beego中的HttpServer结构体和ControllerRegister结构体不是一个结构体;GIN中的Engine结构体和IRoutes接口的实现不是一个结构体一样.在我们的框架中,表示路由树的抽象也不应该是HTTPServer结构体的一个字段,而应该是一个单独的结构体.
之前我们定义了HttpServer.AddRoute()方法,用于注册路由.但实际上注册路由并不是HTTPServer的职责.HTTPServer是代表服务器的抽象,而非是代表路由树的抽象.
(base) yanglei@yuanhong 05-designRoute % tree ./
./
├── context.go
├── handleFunc.go
├── httpServer.go
├── httpServer_test.go
└── serverInterface.go
0 directories, 5 files
修改前代码即为v1版本
这里提前开个上帝视角给一个结论:这样设计的意义不大.因为即使设计成有子树结构的路由树,最终大部分的操作还是会落在节点上,而不会落在子树上.但还是演示一下这样的代码组织
创建文件router.go:
这里路由森林的设计和GIN/Beego的一样,没什么可讲的
创建文件tree.go:
这里也是一样,每棵树有一个指向根节点的指针,也没什么可讲的
创建文件node.go:
这里需要画图演示一下:
看到这样的代码组织,可以想象到大部分的操作还是会落在node结构体上.因此在node和routers之间定义一层tree,意义并不大.
完整工程结构如下:
1.2 路由森林直接指向树的根节点的路由树结构
初态工程结构如下:
还是v1的代码.
创建文件router.go:
创建文件node.go:
1.2.3 定义注册路由的方法
该方法负责将路由注册到对应的路由树上,当然此时我们还没有实现这个功能.实际上这个方法应该定义在router结构体上,而非HTTPServer结构体上.因为这是router结构体的职责.
router.go:
1.2.4 HTTPServer组合router
httpServer.go:
此处做了2处修改:
HTTPServer结构体添加了一个匿名字段*router
HTTPServer结构体删除了AddRoute()方法
但此时HTTPServer结构体仍然是Server接口的实现,因为HTTPServer结构体组合了router结构体,router结构体实现了AddRoute()方法
Tips:如果想要在HTTPServer结构体中使用命名字段来组合router,则还是需要实现HTTPServer结构体的AddRoute()方法,只不过是在该方法中调用router.AddRoute()`
1.2.5 定义创建路由森林的函数
这里其实返回指针还是实例无所谓,因为数据最终放在了一个map里边.无论你通过实例访问该map还是通过指针访问该map,因为map是引用类型,所以最终二者效果一致.
router.go:
1.2.6 定义创建HTTPServer的函数
httpServer.go:
此处做了1处修改:
完整的工程结构如下: