node.js与dojo完美的融合-开发完全面向对象化

本文介绍如何将Dojo框架整合到Node.js环境中,实现面向对象的开发。通过创建一个简单的测试和一个文件上传的例子,展示了Dojo在Node.js中的应用,强调了Dojo的OO技术在提升开发效率和代码组织清晰度方面的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

最近学习了一下node.js,由于我是dojo出身,所以,觉得node.js并不是非常的面向对象化,并不满足面向对象的几个基本条件“封装”、“继承”、“多态”、“重载”等,虽然这些条件,JS是可以模拟出来的,但是重复的造轮子,会使得开发低下,性能堪忧。于是乎鄙人打算写一个node.js的OO module,然后看了一下dojo1.7的源码,发现原来,dojo1.7已经开始支持node.js了,这样就非常好了,我也不必去造轮子了。好了,废话少说,让我们来来看看,dojo是如何进入node.js的上下文的吧。

该文章分两个部分:
1.我们来做一个小的test,来验证dojo是否已加入node.js的上下文中;
2.我们把nodebeginner里面的一个上传图片的例子,用dojo来完成。

第一部分:
开发环境我们可以采用eclipse来完成。将dojo包导入进去:

Project结构图

最外层的dojo文件夹中放入的是dojo库。我们在这个工程中,新建一个入口类Main.js

(function() {
    this.dojoConfig = {
        has: {
            "host-node": 1 
        }
    };
    require("H:/Project/dojo_nodejs/dojo/dojo/dojo");
    define("Main", [], function() { 
        console.info("Hello World!"); 
    });
})();

这里说明一下,this表示的是node.js的上下文,这里给dojo设置host-node,因为dojo默认的模式是host-browser(浏览器窗口模式)。这里还要把dojo.js这个文件require进来,这样就OK啦。
运行效果:

Hello World

这样,dojo就很轻松的融入到node.js的环境中了,是不是很简单^_^¥。好了,下面在第二部分中我们来做一个上传文件的实例来表现dojo在开发node.js这一块强大的OO技术吧。(BTW:上传文件这个例子其实很简单,但是为了表现出用OO的形式来开发node.js,所以会故意写的有点复杂,请不要喷我<#_#>)

第二部分:
首先我们新建一个cory包,Main.js也需要稍微改一下,如下:

(function() { 
    this.dojoConfig = { 
        has: { 
            "host-node": 1 
        }, 
        paths: { 
            cory: "../../cory" 
        } 
    }; 
    require("H:/Project/dojo_nodejs/dojo/dojo/dojo"); 
    define("Main", [], function() { 
        console.info("Hello World!"); 
    });
})();

paths就是注册自定义包的位置。这里cory包和最外层的dojo文件夹并列。然后在cory包中,一共新建4个类,Server.js、UrlParser.js、Router.js、Page.js。

cory.Server:用于创建http服务器。
cory.UrlParser:用于解析URL。
cory.Router:将解析好URL中的pathname进行路由。
cory.Page:对应相应的URL做出逻辑处理。

下面就把各个类的代码展示给大家,主要是展示其语法,至于逻辑的话,nodebeginner.org有详细介绍。

cory.Server:
define([ 
    "../dojo/_base/kernel", 
    "../dojo/_base/declare", 
    "../dojo/Stateful"
], function(dojo, declare, Stateful) { 
    // summary: 
    // This server to listen the port which you setted. 
    return declare("cory.Server", Stateful, { 
        // default value 
        port: 8888, 
        _http: dojo.http, 
        postscript: function(args) { 
            this.inherited(arguments); 
            if (args && args.port) { 
                this.set("port", args.port); 
            } 
        }, 
        start: function(/*Function?*/callback) { 
            console.debug("Server is starting..."); 
            var _port = this.get("port"); 
            this._http.createServer(function(request, response) { 
                callback(request, response); 
            }).listen(_port); 
            console.debug("Server has started. The port is " + _port + "."); 
        } 
    });
});

 

cory.UrlParser:
define(["../dojo/_base/declare"], function(declare) { 
    return declare("cory.UrlParser", null, { 
        parse2Pathname: function(/*String*/url) { 
            var pathname = dojo.url.parse(url).pathname; 
            console.debug("The current path name is: \"" + pathname + "\"."); 
            return pathname; 
        } 
    });
});

 

cory.Router:
define([
    "../dojo/_base/declare", 
    "../dojo/Stateful"
], function(declare, Stateful) { 
    return declare("cory.Router", Stateful, { 
        request: null, 
        response: null, 
        //根据不同的url地址名称,路由到不同的页面逻辑处理。 
         //返回是否路由成功。 
        rout: function(/*Object*/path, /*String*/pathname) { 
            console.debug("About to route a request for " + pathname); 
            var _classAndFunc = path[pathname]; 
            var res = this.get("response"); 
            if (!_classAndFunc) { 
                console.debug("But this path was not found."); 
                if (res) { 
                    res.writeHead(200, {"Content-Type": "text/plain"}); 
                    res.write("404 Not found"); 
                    res.end(); 
                } 
            } 
            var _lastIndex = _classAndFunc.lastIndexOf("."); 
            var _className = _classAndFunc.substring(0, _lastIndex); 
            var _funcName = _classAndFunc.substring(_lastIndex + 1); 
            var _page = new dojo.getObject(_className)(); 
            _page.set("request", this.get("request")); 
            _page.set("response", res); 
            _page[_funcName](); 
        } 
    });
});

 

cory.Page:
define([
    "../dojo/_base/declare", 
    "../dojo/Stateful"
], function(declare, Stateful) { 
    return declare("cory.Page", Stateful, { 
        request: null, response: null, 

        //@Page(path=["/", "/index"]) 
        displayIndex: function() { 
            console.debug("\"cory.Page.displayIndex\" was called"); 
            var res = this.get("response"); 
            if (res) { 
                var body = 
                '<html>'+ 
                    '<head>'+ 
                        '<meta http-equiv="Content-Type" content="text/html; '+ 
                        'charset=UTF-8" />'+ 
                    '</head>'+ 
                    '<body>'+ 
                        '<form action="/upload" method="post" enctype="multipart/form-data">'+ 
                            '<input type="file" name="upload" />'+ 
                            '<input type="submit" value="Upload file" />'+ 
                        '</form>'+ 
                    '</body>'+ 
                '</html>'; 
                res.writeHead(200, {"Content-Type": "text/html"}); 
                res.write(body); 
                res.end(); 
            } 
        }, 

        //@Page(path=["/upload"]) 
        upload: function() { 
            console.debug("\"cory.Page.upload\" was called"); 
            var req = this.get("request"),
                res = this.get("response"); 
            if (req && res) { 
                var form = new dojo.formidable.IncomingForm(); 
                console.debug("about to parse"); 
                form.parse(req, function(error, fields, files) { 
                    console.debug("parsing done."); 
                    dojo.fs.renameSync(files.upload.path, "C:\\Documents and Settings\\Cory\\Local Settings\\Temp\\test.png"); 
                    res.writeHead(200, {"Content-Type": "text/html"}); 
                    res.write("received image:"); 
                    res.write("<img src='/show' />"); 
                    res.end(); 
                }); 
            } 
        }, 
        
        //@Page(path=["/show"]) 
        show: function() { 
            console.debug("\"cory.Page.show\" was called"); 
            var res = this.get("response"); 
            if (res) { 
                dojo.fs.readFile("C:\\Documents and Settings\\Cory\\Local Settings\\Temp\\test.png", "binary", function(error, file){ 
                    if (error) { 
                        res.writeHead(500, {"Content-Type": "text/plain"}); 
                        res.write(error + "\n"); 
                    } else { 
                        res.writeHead(200, {"Content-Type": "image/x-png"}); 
                        res.write(file, "binary"); 
                    } 
                    res.end(); 
                }) 
            } 
        } 
    });
});

 

Main.js也需要一点小改动:

(function() { 
    this.dojoConfig = { 
        has: { 
            "host-node": 1 
        }, 
        paths: { 
            cory: "../../cory" 
        } 
    }; 
    require("H:/Project/dojo_nodejs/dojo/dojo/dojo"); 
    var d = dojo; 
    ["http", "url", "fs", "formidable"].forEach(function(requiredName) { 
        d[requiredName] = require(requiredName); 
    }); 
    define("Main", [ 
        "dojo/_base/kernel", 
        "cory/Server", 
        "cory/UrlParser", 
        "cory/Router", 
        "cory/Page" 
    ], function(dojo, Server, UrlParser, Router) { 
        //这里将地址和类中的方法进行绑定。 
         //其中cory.Page是页面类,后面的.displayIndex、.upload、.show都是该类的方法。 
         var pathMap = { 
            "/": "cory.Page.displayIndex", 
            "/index": "cory.Page.displayIndex", 
            "/upload": "cory.Page.upload", 
            "/show": "cory.Page.show" 
        }; 
        var server = new Server(); 
        server.set("port", 8888); 
        server.start(function(request, response) { 
            var router = new Router(); 
            router.set("request", request); 
            router.set("response", response); 
            router.rout(pathMap, new UrlParser().parse2Pathname(request.url)); 
        }); 
    });
})();

运行效果:

文件上传

上传成功并显示图片

后台控制台运行效果:

控制台输出

怎么样,这样的面向对象的方式,让思路更清晰,要比nodebeginner上的例子,引用传来传去的清晰多了吧。

后记:如果采用dojo来开发node.js后台程序,那么,可以继续封装成,类似于servlet形式,甚至可以进行json配置等。这样更有利于学习成本的降低,减少开发大型后台的人力、时间成本等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值