Node Web学习笔记(10)-请求处理模块

最近看了一篇某位大神写的Node教程,其中有一段如是说到:

将函数作为参数传递并不仅仅出于技术上的考量。对软件设计来说,这其实是个哲学问题。
想想这样的场景:在 index 文件中,我们可以将 router 对象传递进去,服务器随后可以调用这个对象的 route 函数。就像这样,我们传递一个东西,然后服务器利用这个东西来完成一些事。 『嗨那个叫路由的东西,能帮我把这个路由一下吗?』
但是服务器其实不需要这样的东西。它只需要把事情做完就行,其实为了把事情做完,你根本不需要东西,你需要的是动作。
也就是说,你不需要名词,你需要动词。

然后看了看最近写的Node Web学习笔记(9),在针对路由转发的这块,我都是将路由模块直接通过require引入到了服务器中,但是正如上所说,服务器并不需要路由器,它需要的只是路由这个动作。

不知道我的理解是否正确,于是我将代码修改如下:

1、app.js

1
2
3
4
//app.js
var server = require("./server.js");
var router = require("./router.js");
server.startServer(router.route); //将路由函数当做参数传递给服务器

2、server.js

1
2
3
4
5
6
7
8
9
10
11
//server.js
var http = require('http');
//var router = require("./router.js"); 这里就不用再引用路由器模块了
function startServer(route){ //将路由函数赋予它
http.createServer(function(req,res){
route(req,res);
console.log("等待路由转发");
}).listen(8888);
console.log("Your server is start @port 8888");
}
exports.startServer = startServer;

这样看起来,服务器模块显得更加的简洁了。下面重点来看路由器模块的代码编写。

3、router.js

1
2
3
4
5
6
7
8
9
10
11
12
13
//router.js
var url = require('url');
var reqHandler = require("./reqHandler.js");
function route(req,res){
var pathname = url.parse(req.url).pathname;
console.log("访问路径为:" + pathname);
var handle = new reqHandler();
if (pathname == "/") handle.start(res);
else if(pathname == "/index") handle.start(res);
else if(pathname == "/show") handle.show(res);
else handle.notFound(res);
}
exports.route = route;

判断路径的功能仍然交给了路由器模块,然而路由器模块在判断路径后,直接调用请求处理模块来处理。这样有一个好处就是分离了解析路径和请求处理,避免了对于不同路径而处理一样的请求的重复代码。同时也可以在reqHandler模块中更清晰的看到服务端有哪些请求业务。接下来看看请求处理模块。

4、reHandler.js

为了解放路由模块,我们把处理请求的内容交给了请求处理模块reqHandler,该模块的功能就是处理请求,客户端对服务器发起了一个请求,服务器端要对该请求进行分析和处理,那么这个模块的功能就是分析和处理请求。这里的例子处理请求就是返回一个页面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//reqHandler.js
function reqHandler(res){
this.start = function(res){
res.writeHead(200,{"Content-Type":"text/html"});
res.end("This is a index page");
}
this.show = function(res){
res.writeHead(200,{"Content-Type":"text/html"});
res.end("Show page");
}
this.notFound = function(res){
res.writeHead(200,{"Content-Type":"text/html"});
res.end("404 NOT FOUND");
}
/*** 这里可以轻易的添加另外一个页面或者功能
this.another = function(res){
doSomething();
}
*/
}
module.exports = reqHandler;

思考

上面的代码结构已经比之前写的那样要好多了,但是,你也许很快就会发现,路由器模块的if...else语句真的很令人讨厌,当我要添加一个页面的时候,就要在路由器模块中改动代码(加上一句else if),那么随着页面越来越多,if...else语句就会越来越长,这样并不好,那么如何提高的路由器模块的重复利用性呢?